From 3f141459a66fe66e6dc25d579d0cda80662f0895 Mon Sep 17 00:00:00 2001 From: Bingus Date: Thu, 25 May 2023 10:27:27 -0700 Subject: [PATCH 1/9] Fixed issue where quads of different types were not ordered. --- wgpu/src/backend.rs | 8 ++++++-- wgpu/src/layer.rs | 42 ++++++++++++++++++++++++++++++++++++++++- wgpu/src/layer/quad.rs | 9 +++++++++ wgpu/src/quad.rs | 43 +++++++++++++++++++++++++++++++----------- 4 files changed, 88 insertions(+), 14 deletions(-) diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index def80a8100..764a033bf2 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -265,8 +265,12 @@ impl Backend { } if !layer.quads.is_empty() { - self.quad_pipeline - .render(quad_layer, bounds, &mut render_pass); + self.quad_pipeline.render( + quad_layer, + bounds, + &layer.quads.order, + &mut render_pass, + ); quad_layer += 1; } diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index bf5c4c0a30..f5c4b57677 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -43,6 +43,12 @@ pub struct Quads { /// The gradient quads of the [`Layer`]. pub gradients: Vec, + + /// The quad order of the [`Layer`]; stored as a tuple of the quad type & its count. + pub order: Vec<(quad::Order, usize)>, + + // The last index of quad ordering. + index: usize, } impl Quads { @@ -174,12 +180,13 @@ impl<'a> Layer<'a> { border_width: *border_width, }; - match background { + let quad_order = match background { Background::Color(color) => { layer.quads.solids.push(quad::Solid { color: color.into_linear(), quad, }); + quad::Order::Solid } Background::Gradient(gradient) => { let quad = quad::Gradient { @@ -194,8 +201,41 @@ impl<'a> Layer<'a> { }; layer.quads.gradients.push(quad); + quad::Order::Gradient } }; + + match (layer.quads.order.get_mut(layer.quads.index), quad_order) + { + (Some((quad_order, count)), quad::Order::Solid) => { + match quad_order { + quad::Order::Solid => { + *count += 1; + } + quad::Order::Gradient => { + layer.quads.order.push((quad::Order::Solid, 1)); + layer.quads.index += 1; + } + } + } + (Some((quad_order, count)), quad::Order::Gradient) => { + match quad_order { + quad::Order::Solid => { + layer + .quads + .order + .push((quad::Order::Gradient, 1)); + layer.quads.index += 1; + } + quad::Order::Gradient => { + *count += 1; + } + } + } + (None, _) => { + layer.quads.order.push((quad_order, 1)); + } + } } Primitive::Image { handle, bounds } => { let layer = &mut layers[current_layer]; diff --git a/wgpu/src/layer/quad.rs b/wgpu/src/layer/quad.rs index 0bf7837a9c..aaaebd5b70 100644 --- a/wgpu/src/layer/quad.rs +++ b/wgpu/src/layer/quad.rs @@ -49,3 +49,12 @@ unsafe impl Pod for Gradient {} #[allow(unsafe_code)] unsafe impl Zeroable for Gradient {} + +#[derive(Debug, Copy, Clone)] +/// The identifier of a quad, used for ordering. +pub enum Order { + /// A solid quad + Solid, + /// A gradient quad + Gradient, +} diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index 0125ec0bf8..a05e5468aa 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -1,6 +1,6 @@ use crate::core::Rectangle; use crate::graphics::Transformation; -use crate::layer; +use crate::layer::{self, quad}; use std::mem; use wgpu::util::DeviceExt; @@ -87,6 +87,7 @@ impl Pipeline { &'a self, layer: usize, bounds: Rectangle, + ordering: &Vec<(quad::Order, usize)>, render_pass: &mut wgpu::RenderPass<'a>, ) { if let Some(layer) = self.layers.get(layer) { @@ -102,14 +103,30 @@ impl Pipeline { ); render_pass.set_vertex_buffer(0, self.vertices.slice(..)); - if layer.solid.instance_count > 0 { - render_pass.set_pipeline(&self.solid.pipeline); - layer.solid.draw(&layer.constants, render_pass); - } - - if layer.gradient.instance_count > 0 { - render_pass.set_pipeline(&self.gradient.pipeline); - layer.gradient.draw(&layer.constants, render_pass); + let mut solid_offset = 0; + let mut gradient_offset = 0; + + for (quad_order, count) in ordering { + match quad_order { + quad::Order::Solid => { + render_pass.set_pipeline(&self.solid.pipeline); + layer.solid.draw( + &layer.constants, + render_pass, + solid_offset..(solid_offset + count), + ); + solid_offset += count; + } + quad::Order::Gradient => { + render_pass.set_pipeline(&self.gradient.pipeline); + layer.gradient.draw( + &layer.constants, + render_pass, + gradient_offset..(gradient_offset + count), + ); + gradient_offset += count; + } + } } } } @@ -198,6 +215,7 @@ mod solid { use crate::layer::quad; use crate::quad::{color_target_state, Vertex, INDICES, INITIAL_INSTANCES}; use crate::Buffer; + use std::ops::Range; #[derive(Debug)] pub struct Pipeline { @@ -229,6 +247,7 @@ mod solid { &'a self, constants: &'a wgpu::BindGroup, render_pass: &mut wgpu::RenderPass<'a>, + range: Range, ) { #[cfg(feature = "tracing")] let _ = tracing::info_span!("Wgpu::Quad::Solid", "DRAW").entered(); @@ -239,7 +258,7 @@ mod solid { render_pass.draw_indexed( 0..INDICES.len() as u32, 0, - 0..self.instance_count as u32, + range.start as u32..range.end as u32, ); } } @@ -327,6 +346,7 @@ mod gradient { use crate::layer::quad; use crate::quad::{color_target_state, Vertex, INDICES, INITIAL_INSTANCES}; use crate::Buffer; + use std::ops::Range; #[derive(Debug)] pub struct Pipeline { @@ -358,6 +378,7 @@ mod gradient { &'a self, constants: &'a wgpu::BindGroup, render_pass: &mut wgpu::RenderPass<'a>, + range: Range, ) { #[cfg(feature = "tracing")] let _ = @@ -369,7 +390,7 @@ mod gradient { render_pass.draw_indexed( 0..INDICES.len() as u32, 0, - 0..self.instance_count as u32, + range.start as u32..range.end as u32, ); } } From eb6c663420a28e087c91c39e376db3c294b5aea1 Mon Sep 17 00:00:00 2001 From: Bingus Date: Fri, 26 May 2023 09:55:49 -0700 Subject: [PATCH 2/9] Adjusted `Quads` struct to be opaque `quad::Layer`. --- wgpu/src/backend.rs | 2 +- wgpu/src/layer.rs | 87 ++--------------------------------------- wgpu/src/layer/quad.rs | 89 ++++++++++++++++++++++++++++++++++++++++++ wgpu/src/quad.rs | 37 +++++++----------- 4 files changed, 109 insertions(+), 106 deletions(-) diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 764a033bf2..844987f200 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -268,7 +268,7 @@ impl Backend { self.quad_pipeline.render( quad_layer, bounds, - &layer.quads.order, + &layer.quads, &mut render_pass, ); diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index f5c4b57677..4e028eac40 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -12,8 +12,7 @@ pub use text::Text; use crate::core; use crate::core::alignment; -use crate::core::{Background, Color, Font, Point, Rectangle, Size, Vector}; -use crate::graphics::gradient; +use crate::core::{Color, Font, Point, Rectangle, Size, Vector}; use crate::graphics::{Primitive, Viewport}; /// A group of primitives that should be clipped together. @@ -23,7 +22,7 @@ pub struct Layer<'a> { pub bounds: Rectangle, /// The quads of the [`Layer`]. - pub quads: Quads, + pub quads: quad::Layer, /// The triangle meshes of the [`Layer`]. pub meshes: Vec>, @@ -35,35 +34,12 @@ pub struct Layer<'a> { pub images: Vec, } -/// The quads of the [`Layer`]. -#[derive(Default, Debug)] -pub struct Quads { - /// The solid quads of the [`Layer`]. - pub solids: Vec, - - /// The gradient quads of the [`Layer`]. - pub gradients: Vec, - - /// The quad order of the [`Layer`]; stored as a tuple of the quad type & its count. - pub order: Vec<(quad::Order, usize)>, - - // The last index of quad ordering. - index: usize, -} - -impl Quads { - /// Returns true if there are no quads of any type in [`Quads`]. - pub fn is_empty(&self) -> bool { - self.solids.is_empty() && self.gradients.is_empty() - } -} - impl<'a> Layer<'a> { /// Creates a new [`Layer`] with the given clipping bounds. pub fn new(bounds: Rectangle) -> Self { Self { bounds, - quads: Quads::default(), + quads: quad::Layer::default(), meshes: Vec::new(), text: Vec::new(), images: Vec::new(), @@ -180,62 +156,7 @@ impl<'a> Layer<'a> { border_width: *border_width, }; - let quad_order = match background { - Background::Color(color) => { - layer.quads.solids.push(quad::Solid { - color: color.into_linear(), - quad, - }); - quad::Order::Solid - } - Background::Gradient(gradient) => { - let quad = quad::Gradient { - gradient: gradient::pack( - gradient, - Rectangle::new( - quad.position.into(), - quad.size.into(), - ), - ), - quad, - }; - - layer.quads.gradients.push(quad); - quad::Order::Gradient - } - }; - - match (layer.quads.order.get_mut(layer.quads.index), quad_order) - { - (Some((quad_order, count)), quad::Order::Solid) => { - match quad_order { - quad::Order::Solid => { - *count += 1; - } - quad::Order::Gradient => { - layer.quads.order.push((quad::Order::Solid, 1)); - layer.quads.index += 1; - } - } - } - (Some((quad_order, count)), quad::Order::Gradient) => { - match quad_order { - quad::Order::Solid => { - layer - .quads - .order - .push((quad::Order::Gradient, 1)); - layer.quads.index += 1; - } - quad::Order::Gradient => { - *count += 1; - } - } - } - (None, _) => { - layer.quads.order.push((quad_order, 1)); - } - } + layer.quads.add(quad, background); } Primitive::Image { handle, bounds } => { let layer = &mut layers[current_layer]; diff --git a/wgpu/src/layer/quad.rs b/wgpu/src/layer/quad.rs index aaaebd5b70..284a761807 100644 --- a/wgpu/src/layer/quad.rs +++ b/wgpu/src/layer/quad.rs @@ -1,4 +1,5 @@ //! A rectangle with certain styled properties. +use crate::core::{Background, Rectangle}; use crate::graphics::gradient; use bytemuck::{Pod, Zeroable}; @@ -58,3 +59,91 @@ pub enum Order { /// A gradient quad Gradient, } + +/// A group of [`Quad`]s rendered together. +#[derive(Default, Debug)] +pub struct Layer { + /// The solid quads of the [`Layer`]. + solids: Vec, + + /// The gradient quads of the [`Layer`]. + gradients: Vec, + + /// The quad order of the [`Layer`]; stored as a tuple of the quad type & its count. + order: Vec<(Order, usize)>, + + /// The last index of quad ordering. + index: usize, +} + +impl Layer { + /// Returns true if there are no quads of any type in [`Quads`]. + pub fn is_empty(&self) -> bool { + self.solids.is_empty() && self.gradients.is_empty() + } + + /// The [`Solid`] quads of the [`Layer`]. + pub fn solids(&self) -> &[Solid] { + &self.solids + } + + /// The [`Gradient`] quads of the [`Layer`]. + pub fn gradients(&self) -> &[Gradient] { + &self.gradients + } + + /// The order of quads within the [`Layer`], grouped by (type, count) for rendering in batches. + pub fn ordering(&self) -> &[(Order, usize)] { + &self.order + } + + /// Adds a [`Quad`] with the provided `Background` type to the quad [`Layer`]. + pub fn add(&mut self, quad: Quad, background: &Background) { + let quad_order = match background { + Background::Color(color) => { + self.solids.push(Solid { + color: color.into_linear(), + quad, + }); + + Order::Solid + } + Background::Gradient(gradient) => { + let quad = Gradient { + gradient: gradient::pack( + gradient, + Rectangle::new(quad.position.into(), quad.size.into()), + ), + quad, + }; + + self.gradients.push(quad); + Order::Gradient + } + }; + + match (self.order.get_mut(self.index), quad_order) { + (Some((quad_order, count)), Order::Solid) => match quad_order { + Order::Solid => { + *count += 1; + } + Order::Gradient => { + self.order.push((Order::Solid, 1)); + self.index += 1; + } + }, + (Some((quad_order, count)), Order::Gradient) => match quad_order { + Order::Solid => { + self.order.push((Order::Gradient, 1)); + self.index += 1; + } + Order::Gradient => { + *count += 1; + } + }, + (None, _) => { + self.order.push((quad_order, 1)); + } + } + } +} diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index a05e5468aa..065da15366 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -1,6 +1,6 @@ use crate::core::Rectangle; use crate::graphics::Transformation; -use crate::layer::{self, quad}; +use crate::layer::quad; use std::mem; use wgpu::util::DeviceExt; @@ -69,7 +69,7 @@ impl Pipeline { &mut self, device: &wgpu::Device, queue: &wgpu::Queue, - instances: &layer::Quads, + quads: &quad::Layer, transformation: Transformation, scale: f32, ) { @@ -78,7 +78,7 @@ impl Pipeline { } let layer = &mut self.layers[self.prepare_layer]; - layer.prepare(device, queue, instances, transformation, scale); + layer.prepare(device, queue, quads, transformation, scale); self.prepare_layer += 1; } @@ -87,7 +87,7 @@ impl Pipeline { &'a self, layer: usize, bounds: Rectangle, - ordering: &Vec<(quad::Order, usize)>, + quads: &quad::Layer, render_pass: &mut wgpu::RenderPass<'a>, ) { if let Some(layer) = self.layers.get(layer) { @@ -106,7 +106,7 @@ impl Pipeline { let mut solid_offset = 0; let mut gradient_offset = 0; - for (quad_order, count) in ordering { + for (quad_order, count) in quads.ordering() { match quad_order { quad::Order::Solid => { render_pass.set_pipeline(&self.solid.pipeline); @@ -177,7 +177,7 @@ impl Layer { &mut self, device: &wgpu::Device, queue: &wgpu::Queue, - instances: &layer::Quads, + quads: &quad::Layer, transformation: Transformation, scale: f32, ) { @@ -192,22 +192,15 @@ impl Layer { bytemuck::bytes_of(&uniforms), ); - let _ = self.solid.instances.resize(device, instances.solids.len()); - let _ = self - .gradient - .instances - .resize(device, instances.gradients.len()); - let _ = - self.solid - .instances - .write(queue, 0, instances.solids.as_slice()); - self.solid.instance_count = instances.solids.len(); - let _ = self.gradient.instances.write( - queue, - 0, - instances.gradients.as_slice(), - ); - self.gradient.instance_count = instances.gradients.len(); + let solids = quads.solids(); + let gradients = quads.gradients(); + + let _ = self.solid.instances.resize(device, solids.len()); + let _ = self.gradient.instances.resize(device, gradients.len()); + let _ = self.solid.instances.write(queue, 0, solids); + self.solid.instance_count = solids.len(); + let _ = self.gradient.instances.write(queue, 0, gradients); + self.gradient.instance_count = gradients.len(); } } From fe9da174cafffbd77eb351c51ba017cf039a4cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 30 May 2023 00:56:52 +0200 Subject: [PATCH 3/9] Move `layer::quad` types to `quad` module Not sure why I split these to begin with! --- wgpu/src/layer.rs | 7 +- wgpu/src/layer/quad.rs | 149 --------------- wgpu/src/quad.rs | 390 +++++++++++--------------------------- wgpu/src/quad/gradient.rs | 161 ++++++++++++++++ wgpu/src/quad/solid.rs | 136 +++++++++++++ 5 files changed, 408 insertions(+), 435 deletions(-) delete mode 100644 wgpu/src/layer/quad.rs create mode 100644 wgpu/src/quad/gradient.rs create mode 100644 wgpu/src/quad/solid.rs diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index 4e028eac40..1a870c159e 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -3,17 +3,16 @@ mod image; mod text; pub mod mesh; -pub mod quad; pub use image::Image; pub use mesh::Mesh; -pub use quad::Quad; pub use text::Text; use crate::core; use crate::core::alignment; use crate::core::{Color, Font, Point, Rectangle, Size, Vector}; use crate::graphics::{Primitive, Viewport}; +use crate::quad::{self, Quad}; /// A group of primitives that should be clipped together. #[derive(Debug)] @@ -22,7 +21,7 @@ pub struct Layer<'a> { pub bounds: Rectangle, /// The quads of the [`Layer`]. - pub quads: quad::Layer, + pub quads: quad::Batch, /// The triangle meshes of the [`Layer`]. pub meshes: Vec>, @@ -39,7 +38,7 @@ impl<'a> Layer<'a> { pub fn new(bounds: Rectangle) -> Self { Self { bounds, - quads: quad::Layer::default(), + quads: quad::Batch::default(), meshes: Vec::new(), text: Vec::new(), images: Vec::new(), diff --git a/wgpu/src/layer/quad.rs b/wgpu/src/layer/quad.rs deleted file mode 100644 index 284a761807..0000000000 --- a/wgpu/src/layer/quad.rs +++ /dev/null @@ -1,149 +0,0 @@ -//! A rectangle with certain styled properties. -use crate::core::{Background, Rectangle}; -use crate::graphics::gradient; -use bytemuck::{Pod, Zeroable}; - -/// The properties of a quad. -#[derive(Clone, Copy, Debug, Pod, Zeroable)] -#[repr(C)] -pub struct Quad { - /// The position of the [`Quad`]. - pub position: [f32; 2], - - /// The size of the [`Quad`]. - pub size: [f32; 2], - - /// The border color of the [`Quad`], in __linear RGB__. - pub border_color: [f32; 4], - - /// The border radii of the [`Quad`]. - pub border_radius: [f32; 4], - - /// The border width of the [`Quad`]. - pub border_width: f32, -} - -/// A quad filled with a solid color. -#[derive(Clone, Copy, Debug, Pod, Zeroable)] -#[repr(C)] -pub struct Solid { - /// The background color data of the quad. - pub color: [f32; 4], - - /// The [`Quad`] data of the [`Solid`]. - pub quad: Quad, -} - -/// A quad filled with interpolated colors. -#[derive(Clone, Copy, Debug)] -#[repr(C)] -pub struct Gradient { - /// The background gradient data of the quad. - pub gradient: gradient::Packed, - - /// The [`Quad`] data of the [`Gradient`]. - pub quad: Quad, -} - -#[allow(unsafe_code)] -unsafe impl Pod for Gradient {} - -#[allow(unsafe_code)] -unsafe impl Zeroable for Gradient {} - -#[derive(Debug, Copy, Clone)] -/// The identifier of a quad, used for ordering. -pub enum Order { - /// A solid quad - Solid, - /// A gradient quad - Gradient, -} - -/// A group of [`Quad`]s rendered together. -#[derive(Default, Debug)] -pub struct Layer { - /// The solid quads of the [`Layer`]. - solids: Vec, - - /// The gradient quads of the [`Layer`]. - gradients: Vec, - - /// The quad order of the [`Layer`]; stored as a tuple of the quad type & its count. - order: Vec<(Order, usize)>, - - /// The last index of quad ordering. - index: usize, -} - -impl Layer { - /// Returns true if there are no quads of any type in [`Quads`]. - pub fn is_empty(&self) -> bool { - self.solids.is_empty() && self.gradients.is_empty() - } - - /// The [`Solid`] quads of the [`Layer`]. - pub fn solids(&self) -> &[Solid] { - &self.solids - } - - /// The [`Gradient`] quads of the [`Layer`]. - pub fn gradients(&self) -> &[Gradient] { - &self.gradients - } - - /// The order of quads within the [`Layer`], grouped by (type, count) for rendering in batches. - pub fn ordering(&self) -> &[(Order, usize)] { - &self.order - } - - /// Adds a [`Quad`] with the provided `Background` type to the quad [`Layer`]. - pub fn add(&mut self, quad: Quad, background: &Background) { - let quad_order = match background { - Background::Color(color) => { - self.solids.push(Solid { - color: color.into_linear(), - quad, - }); - - Order::Solid - } - Background::Gradient(gradient) => { - let quad = Gradient { - gradient: gradient::pack( - gradient, - Rectangle::new(quad.position.into(), quad.size.into()), - ), - quad, - }; - - self.gradients.push(quad); - Order::Gradient - } - }; - - match (self.order.get_mut(self.index), quad_order) { - (Some((quad_order, count)), Order::Solid) => match quad_order { - Order::Solid => { - *count += 1; - } - Order::Gradient => { - self.order.push((Order::Solid, 1)); - self.index += 1; - } - }, - (Some((quad_order, count)), Order::Gradient) => match quad_order { - Order::Solid => { - self.order.push((Order::Gradient, 1)); - self.index += 1; - } - Order::Gradient => { - *count += 1; - } - }, - (None, _) => { - self.order.push((quad_order, 1)); - } - } - } -} diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index 065da15366..375b0cd7c4 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -1,10 +1,17 @@ -use crate::core::Rectangle; -use crate::graphics::Transformation; -use crate::layer::quad; +mod gradient; +mod solid; -use std::mem; +use gradient::Gradient; +use solid::Solid; + +use crate::core::{Background, Rectangle}; +use crate::graphics::{self, Transformation}; + +use bytemuck::{Pod, Zeroable}; use wgpu::util::DeviceExt; +use std::mem; + #[cfg(feature = "tracing")] use tracing::info_span; @@ -69,7 +76,7 @@ impl Pipeline { &mut self, device: &wgpu::Device, queue: &wgpu::Queue, - quads: &quad::Layer, + quads: &Batch, transformation: Transformation, scale: f32, ) { @@ -87,7 +94,7 @@ impl Pipeline { &'a self, layer: usize, bounds: Rectangle, - quads: &quad::Layer, + quads: &Batch, render_pass: &mut wgpu::RenderPass<'a>, ) { if let Some(layer) = self.layers.get(layer) { @@ -106,9 +113,9 @@ impl Pipeline { let mut solid_offset = 0; let mut gradient_offset = 0; - for (quad_order, count) in quads.ordering() { + for (quad_order, count) in &quads.order { match quad_order { - quad::Order::Solid => { + Order::Solid => { render_pass.set_pipeline(&self.solid.pipeline); layer.solid.draw( &layer.constants, @@ -117,7 +124,7 @@ impl Pipeline { ); solid_offset += count; } - quad::Order::Gradient => { + Order::Gradient => { render_pass.set_pipeline(&self.gradient.pipeline); layer.gradient.draw( &layer.constants, @@ -177,7 +184,7 @@ impl Layer { &mut self, device: &wgpu::Device, queue: &wgpu::Queue, - quads: &quad::Layer, + quads: &Batch, transformation: Transformation, scale: f32, ) { @@ -192,303 +199,122 @@ impl Layer { bytemuck::bytes_of(&uniforms), ); - let solids = quads.solids(); - let gradients = quads.gradients(); + let _ = self.solid.instances.resize(device, quads.solids.len()); + let _ = self + .gradient + .instances + .resize(device, quads.gradients.len()); + + let _ = self.solid.instances.write(queue, 0, &quads.solids); + let _ = self.gradient.instances.write(queue, 0, &quads.gradients); - let _ = self.solid.instances.resize(device, solids.len()); - let _ = self.gradient.instances.resize(device, gradients.len()); - let _ = self.solid.instances.write(queue, 0, solids); - self.solid.instance_count = solids.len(); - let _ = self.gradient.instances.write(queue, 0, gradients); - self.gradient.instance_count = gradients.len(); + self.solid.instance_count = quads.solids.len(); + self.gradient.instance_count = quads.gradients.len(); } } -mod solid { - use crate::layer::quad; - use crate::quad::{color_target_state, Vertex, INDICES, INITIAL_INSTANCES}; - use crate::Buffer; - use std::ops::Range; - - #[derive(Debug)] - pub struct Pipeline { - pub pipeline: wgpu::RenderPipeline, - } +/// The properties of a quad. +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +#[repr(C)] +pub struct Quad { + /// The position of the [`Quad`]. + pub position: [f32; 2], - #[derive(Debug)] - pub struct Layer { - pub instances: Buffer, - pub instance_count: usize, - } + /// The size of the [`Quad`]. + pub size: [f32; 2], - impl Layer { - pub fn new(device: &wgpu::Device) -> Self { - let instances = Buffer::new( - device, - "iced_wgpu.quad.solid.buffer", - INITIAL_INSTANCES, - wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, - ); + /// The border color of the [`Quad`], in __linear RGB__. + pub border_color: [f32; 4], - Self { - instances, - instance_count: 0, - } - } + /// The border radii of the [`Quad`]. + pub border_radius: [f32; 4], - pub fn draw<'a>( - &'a self, - constants: &'a wgpu::BindGroup, - render_pass: &mut wgpu::RenderPass<'a>, - range: Range, - ) { - #[cfg(feature = "tracing")] - let _ = tracing::info_span!("Wgpu::Quad::Solid", "DRAW").entered(); - - render_pass.set_bind_group(0, constants, &[]); - render_pass.set_vertex_buffer(1, self.instances.slice(..)); - - render_pass.draw_indexed( - 0..INDICES.len() as u32, - 0, - range.start as u32..range.end as u32, - ); - } - } + /// The border width of the [`Quad`]. + pub border_width: f32, +} - impl Pipeline { - pub fn new( - device: &wgpu::Device, - format: wgpu::TextureFormat, - constants_layout: &wgpu::BindGroupLayout, - ) -> Self { - let layout = device.create_pipeline_layout( - &wgpu::PipelineLayoutDescriptor { - label: Some("iced_wgpu.quad.solid.pipeline"), - push_constant_ranges: &[], - bind_group_layouts: &[constants_layout], - }, - ); +/// A group of [`Quad`]s rendered together. +#[derive(Default, Debug)] +pub struct Batch { + /// The solid quads of the [`Layer`]. + solids: Vec, - let shader = - device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: Some("iced_wgpu.quad.solid.shader"), - source: wgpu::ShaderSource::Wgsl( - std::borrow::Cow::Borrowed(include_str!( - "shader/quad.wgsl" - )), - ), - }); + /// The gradient quads of the [`Layer`]. + gradients: Vec, - let pipeline = device.create_render_pipeline( - &wgpu::RenderPipelineDescriptor { - label: Some("iced_wgpu.quad.solid.pipeline"), - layout: Some(&layout), - vertex: wgpu::VertexState { - module: &shader, - entry_point: "solid_vs_main", - buffers: &[ - Vertex::buffer_layout(), - wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::() - as u64, - step_mode: wgpu::VertexStepMode::Instance, - attributes: &wgpu::vertex_attr_array!( - // Color - 1 => Float32x4, - // Position - 2 => Float32x2, - // Size - 3 => Float32x2, - // Border color - 4 => Float32x4, - // Border radius - 5 => Float32x4, - // Border width - 6 => Float32, - ), - }, - ], - }, - fragment: Some(wgpu::FragmentState { - module: &shader, - entry_point: "solid_fs_main", - targets: &color_target_state(format), - }), - primitive: wgpu::PrimitiveState { - topology: wgpu::PrimitiveTopology::TriangleList, - front_face: wgpu::FrontFace::Cw, - ..Default::default() - }, - depth_stencil: None, - multisample: wgpu::MultisampleState { - count: 1, - mask: !0, - alpha_to_coverage_enabled: false, - }, - multiview: None, - }, - ); + /// The quad order of the [`Layer`]; stored as a tuple of the quad type & its count. + order: Vec<(Order, usize)>, - Self { pipeline } - } - } + /// The last index of quad ordering. + index: usize, } -mod gradient { - use crate::layer::quad; - use crate::quad::{color_target_state, Vertex, INDICES, INITIAL_INSTANCES}; - use crate::Buffer; - use std::ops::Range; - - #[derive(Debug)] - pub struct Pipeline { - pub pipeline: wgpu::RenderPipeline, - } - - #[derive(Debug)] - pub struct Layer { - pub instances: Buffer, - pub instance_count: usize, +impl Batch { + /// Returns true if there are no quads of any type in [`Quads`]. + pub fn is_empty(&self) -> bool { + self.solids.is_empty() && self.gradients.is_empty() } - impl Layer { - pub fn new(device: &wgpu::Device) -> Self { - let instances = Buffer::new( - device, - "iced_wgpu.quad.gradient.buffer", - INITIAL_INSTANCES, - wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, - ); + /// Adds a [`Quad`] with the provided `Background` type to the quad [`Layer`]. + pub fn add(&mut self, quad: Quad, background: &Background) { + let quad_order = match background { + Background::Color(color) => { + self.solids.push(Solid { + color: color.into_linear(), + quad, + }); - Self { - instances, - instance_count: 0, + Order::Solid } - } - - pub fn draw<'a>( - &'a self, - constants: &'a wgpu::BindGroup, - render_pass: &mut wgpu::RenderPass<'a>, - range: Range, - ) { - #[cfg(feature = "tracing")] - let _ = - tracing::info_span!("Wgpu::Quad::Gradient", "DRAW").entered(); - - render_pass.set_bind_group(0, constants, &[]); - render_pass.set_vertex_buffer(1, self.instances.slice(..)); - - render_pass.draw_indexed( - 0..INDICES.len() as u32, - 0, - range.start as u32..range.end as u32, - ); - } - } - - impl Pipeline { - pub fn new( - device: &wgpu::Device, - format: wgpu::TextureFormat, - constants_layout: &wgpu::BindGroupLayout, - ) -> Self { - let layout = device.create_pipeline_layout( - &wgpu::PipelineLayoutDescriptor { - label: Some("iced_wgpu.quad.gradient.pipeline"), - push_constant_ranges: &[], - bind_group_layouts: &[constants_layout], - }, - ); - - let shader = - device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: Some("iced_wgpu.quad.gradient.shader"), - source: wgpu::ShaderSource::Wgsl( - std::borrow::Cow::Borrowed(include_str!( - "shader/quad.wgsl" - )), + Background::Gradient(gradient) => { + let quad = Gradient { + gradient: graphics::gradient::pack( + gradient, + Rectangle::new(quad.position.into(), quad.size.into()), ), - }); + quad, + }; - let pipeline = - device.create_render_pipeline( - &wgpu::RenderPipelineDescriptor { - label: Some("iced_wgpu.quad.gradient.pipeline"), - layout: Some(&layout), - vertex: wgpu::VertexState { - module: &shader, - entry_point: "gradient_vs_main", - buffers: &[ - Vertex::buffer_layout(), - wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::< - quad::Gradient, - >( - ) - as u64, - step_mode: wgpu::VertexStepMode::Instance, - attributes: &wgpu::vertex_attr_array!( - // Color 1 - 1 => Float32x4, - // Color 2 - 2 => Float32x4, - // Color 3 - 3 => Float32x4, - // Color 4 - 4 => Float32x4, - // Color 5 - 5 => Float32x4, - // Color 6 - 6 => Float32x4, - // Color 7 - 7 => Float32x4, - // Color 8 - 8 => Float32x4, - // Offsets 1-4 - 9 => Float32x4, - // Offsets 5-8 - 10 => Float32x4, - // Direction - 11 => Float32x4, - // Position & Scale - 12 => Float32x4, - // Border color - 13 => Float32x4, - // Border radius - 14 => Float32x4, - // Border width - 15 => Float32 - ), - }, - ], - }, - fragment: Some(wgpu::FragmentState { - module: &shader, - entry_point: "gradient_fs_main", - targets: &color_target_state(format), - }), - primitive: wgpu::PrimitiveState { - topology: wgpu::PrimitiveTopology::TriangleList, - front_face: wgpu::FrontFace::Cw, - ..Default::default() - }, - depth_stencil: None, - multisample: wgpu::MultisampleState { - count: 1, - mask: !0, - alpha_to_coverage_enabled: false, - }, - multiview: None, - }, - ); + self.gradients.push(quad); + Order::Gradient + } + }; - Self { pipeline } + match (self.order.get_mut(self.index), quad_order) { + (Some((quad_order, count)), Order::Solid) => match quad_order { + Order::Solid => { + *count += 1; + } + Order::Gradient => { + self.order.push((Order::Solid, 1)); + self.index += 1; + } + }, + (Some((quad_order, count)), Order::Gradient) => match quad_order { + Order::Solid => { + self.order.push((Order::Gradient, 1)); + self.index += 1; + } + Order::Gradient => { + *count += 1; + } + }, + (None, _) => { + self.order.push((quad_order, 1)); + } } } } +#[derive(Debug, Copy, Clone)] +/// The identifier of a quad, used for ordering. +enum Order { + /// A solid quad + Solid, + /// A gradient quad + Gradient, +} + fn color_target_state( format: wgpu::TextureFormat, ) -> [Option; 1] { diff --git a/wgpu/src/quad/gradient.rs b/wgpu/src/quad/gradient.rs new file mode 100644 index 0000000000..2729afdf96 --- /dev/null +++ b/wgpu/src/quad/gradient.rs @@ -0,0 +1,161 @@ +use crate::graphics::gradient; +use crate::quad::{self, Quad}; +use crate::Buffer; + +use bytemuck::{Pod, Zeroable}; +use std::ops::Range; + +/// A quad filled with interpolated colors. +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct Gradient { + /// The background gradient data of the quad. + pub gradient: gradient::Packed, + + /// The [`Quad`] data of the [`Gradient`]. + pub quad: Quad, +} + +#[allow(unsafe_code)] +unsafe impl Pod for Gradient {} + +#[allow(unsafe_code)] +unsafe impl Zeroable for Gradient {} + +#[derive(Debug)] +pub struct Pipeline { + pub pipeline: wgpu::RenderPipeline, +} + +#[derive(Debug)] +pub struct Layer { + pub instances: Buffer, + pub instance_count: usize, +} + +impl Layer { + pub fn new(device: &wgpu::Device) -> Self { + let instances = Buffer::new( + device, + "iced_wgpu.quad.gradient.buffer", + quad::INITIAL_INSTANCES, + wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, + ); + + Self { + instances, + instance_count: 0, + } + } + + pub fn draw<'a>( + &'a self, + constants: &'a wgpu::BindGroup, + render_pass: &mut wgpu::RenderPass<'a>, + range: Range, + ) { + #[cfg(feature = "tracing")] + let _ = tracing::info_span!("Wgpu::Quad::Gradient", "DRAW").entered(); + + render_pass.set_bind_group(0, constants, &[]); + render_pass.set_vertex_buffer(1, self.instances.slice(..)); + + render_pass.draw_indexed( + 0..quad::INDICES.len() as u32, + 0, + range.start as u32..range.end as u32, + ); + } +} + +impl Pipeline { + pub fn new( + device: &wgpu::Device, + format: wgpu::TextureFormat, + constants_layout: &wgpu::BindGroupLayout, + ) -> Self { + let layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("iced_wgpu.quad.gradient.pipeline"), + push_constant_ranges: &[], + bind_group_layouts: &[constants_layout], + }); + + let shader = + device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("iced_wgpu.quad.gradient.shader"), + source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( + include_str!("../shader/quad.wgsl"), + )), + }); + + let pipeline = + device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("iced_wgpu.quad.gradient.pipeline"), + layout: Some(&layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: "gradient_vs_main", + buffers: &[ + quad::Vertex::buffer_layout(), + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() + as u64, + step_mode: wgpu::VertexStepMode::Instance, + attributes: &wgpu::vertex_attr_array!( + // Color 1 + 1 => Float32x4, + // Color 2 + 2 => Float32x4, + // Color 3 + 3 => Float32x4, + // Color 4 + 4 => Float32x4, + // Color 5 + 5 => Float32x4, + // Color 6 + 6 => Float32x4, + // Color 7 + 7 => Float32x4, + // Color 8 + 8 => Float32x4, + // Offsets 1-4 + 9 => Float32x4, + // Offsets 5-8 + 10 => Float32x4, + // Direction + 11 => Float32x4, + // Position & Scale + 12 => Float32x4, + // Border color + 13 => Float32x4, + // Border radius + 14 => Float32x4, + // Border width + 15 => Float32 + ), + }, + ], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "gradient_fs_main", + targets: &quad::color_target_state(format), + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + front_face: wgpu::FrontFace::Cw, + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: false, + }, + multiview: None, + }); + + Self { pipeline } + } +} diff --git a/wgpu/src/quad/solid.rs b/wgpu/src/quad/solid.rs new file mode 100644 index 0000000000..3540ce3a94 --- /dev/null +++ b/wgpu/src/quad/solid.rs @@ -0,0 +1,136 @@ +use crate::quad::{self, Quad}; +use crate::Buffer; + +use bytemuck::{Pod, Zeroable}; +use std::ops::Range; + +/// A quad filled with a solid color. +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +#[repr(C)] +pub struct Solid { + /// The background color data of the quad. + pub color: [f32; 4], + + /// The [`Quad`] data of the [`Solid`]. + pub quad: Quad, +} + +#[derive(Debug)] +pub struct Pipeline { + pub pipeline: wgpu::RenderPipeline, +} + +#[derive(Debug)] +pub struct Layer { + pub instances: Buffer, + pub instance_count: usize, +} + +impl Layer { + pub fn new(device: &wgpu::Device) -> Self { + let instances = Buffer::new( + device, + "iced_wgpu.quad.solid.buffer", + quad::INITIAL_INSTANCES, + wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, + ); + + Self { + instances, + instance_count: 0, + } + } + + pub fn draw<'a>( + &'a self, + constants: &'a wgpu::BindGroup, + render_pass: &mut wgpu::RenderPass<'a>, + range: Range, + ) { + #[cfg(feature = "tracing")] + let _ = tracing::info_span!("Wgpu::Quad::Solid", "DRAW").entered(); + + render_pass.set_bind_group(0, constants, &[]); + render_pass.set_vertex_buffer(1, self.instances.slice(..)); + + render_pass.draw_indexed( + 0..quad::INDICES.len() as u32, + 0, + range.start as u32..range.end as u32, + ); + } +} + +impl Pipeline { + pub fn new( + device: &wgpu::Device, + format: wgpu::TextureFormat, + constants_layout: &wgpu::BindGroupLayout, + ) -> Self { + let layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("iced_wgpu.quad.solid.pipeline"), + push_constant_ranges: &[], + bind_group_layouts: &[constants_layout], + }); + + let shader = + device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("iced_wgpu.quad.solid.shader"), + source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( + include_str!("../shader/quad.wgsl"), + )), + }); + + let pipeline = + device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("iced_wgpu.quad.solid.pipeline"), + layout: Some(&layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: "solid_vs_main", + buffers: &[ + quad::Vertex::buffer_layout(), + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() + as u64, + step_mode: wgpu::VertexStepMode::Instance, + attributes: &wgpu::vertex_attr_array!( + // Color + 1 => Float32x4, + // Position + 2 => Float32x2, + // Size + 3 => Float32x2, + // Border color + 4 => Float32x4, + // Border radius + 5 => Float32x4, + // Border width + 6 => Float32, + ), + }, + ], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "solid_fs_main", + targets: &quad::color_target_state(format), + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + front_face: wgpu::FrontFace::Cw, + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: false, + }, + multiview: None, + }); + + Self { pipeline } + } +} From 6d650e7f9987aa72913d20c7e538448b518a6150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 30 May 2023 00:59:42 +0200 Subject: [PATCH 4/9] Rename `quad::Order` to `quad::Kind` --- wgpu/src/quad.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index 375b0cd7c4..48ef565edc 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -115,7 +115,7 @@ impl Pipeline { for (quad_order, count) in &quads.order { match quad_order { - Order::Solid => { + Kind::Solid => { render_pass.set_pipeline(&self.solid.pipeline); layer.solid.draw( &layer.constants, @@ -124,7 +124,7 @@ impl Pipeline { ); solid_offset += count; } - Order::Gradient => { + Kind::Gradient => { render_pass.set_pipeline(&self.gradient.pipeline); layer.gradient.draw( &layer.constants, @@ -243,7 +243,7 @@ pub struct Batch { gradients: Vec, /// The quad order of the [`Layer`]; stored as a tuple of the quad type & its count. - order: Vec<(Order, usize)>, + order: Vec<(Kind, usize)>, /// The last index of quad ordering. index: usize, @@ -264,7 +264,7 @@ impl Batch { quad, }); - Order::Solid + Kind::Solid } Background::Gradient(gradient) => { let quad = Gradient { @@ -276,26 +276,26 @@ impl Batch { }; self.gradients.push(quad); - Order::Gradient + Kind::Gradient } }; match (self.order.get_mut(self.index), quad_order) { - (Some((quad_order, count)), Order::Solid) => match quad_order { - Order::Solid => { + (Some((quad_order, count)), Kind::Solid) => match quad_order { + Kind::Solid => { *count += 1; } - Order::Gradient => { - self.order.push((Order::Solid, 1)); + Kind::Gradient => { + self.order.push((Kind::Solid, 1)); self.index += 1; } }, - (Some((quad_order, count)), Order::Gradient) => match quad_order { - Order::Solid => { - self.order.push((Order::Gradient, 1)); + (Some((quad_order, count)), Kind::Gradient) => match quad_order { + Kind::Solid => { + self.order.push((Kind::Gradient, 1)); self.index += 1; } - Order::Gradient => { + Kind::Gradient => { *count += 1; } }, @@ -307,8 +307,8 @@ impl Batch { } #[derive(Debug, Copy, Clone)] -/// The identifier of a quad, used for ordering. -enum Order { +/// The kind of a quad. +enum Kind { /// A solid quad Solid, /// A gradient quad From cd7d33aa8ebc6fbb6666f34aeda3ee96d0fb51e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 30 May 2023 01:14:41 +0200 Subject: [PATCH 5/9] Simplify `order` match statement in `quad::Batch::add` --- wgpu/src/quad.rs | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index 48ef565edc..e25d02afa0 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -244,9 +244,6 @@ pub struct Batch { /// The quad order of the [`Layer`]; stored as a tuple of the quad type & its count. order: Vec<(Kind, usize)>, - - /// The last index of quad ordering. - index: usize, } impl Batch { @@ -257,7 +254,7 @@ impl Batch { /// Adds a [`Quad`] with the provided `Background` type to the quad [`Layer`]. pub fn add(&mut self, quad: Quad, background: &Background) { - let quad_order = match background { + let kind = match background { Background::Color(color) => { self.solids.push(Solid { color: color.into_linear(), @@ -276,37 +273,23 @@ impl Batch { }; self.gradients.push(quad); + Kind::Gradient } }; - match (self.order.get_mut(self.index), quad_order) { - (Some((quad_order, count)), Kind::Solid) => match quad_order { - Kind::Solid => { - *count += 1; - } - Kind::Gradient => { - self.order.push((Kind::Solid, 1)); - self.index += 1; - } - }, - (Some((quad_order, count)), Kind::Gradient) => match quad_order { - Kind::Solid => { - self.order.push((Kind::Gradient, 1)); - self.index += 1; - } - Kind::Gradient => { - *count += 1; - } - }, - (None, _) => { - self.order.push((quad_order, 1)); + match self.order.last_mut() { + Some((last_kind, count)) if kind == *last_kind => { + *count += 1; + } + _ => { + self.order.push((kind, 1)); } } } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] /// The kind of a quad. enum Kind { /// A solid quad From 9659e6a848d76df39c1988e33d248d1c1560271f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 30 May 2023 01:16:30 +0200 Subject: [PATCH 6/9] Improve consistency of match branches in `quad::Batch::add` --- wgpu/src/quad.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index e25d02afa0..62472126b5 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -264,15 +264,13 @@ impl Batch { Kind::Solid } Background::Gradient(gradient) => { - let quad = Gradient { + self.gradients.push(Gradient { gradient: graphics::gradient::pack( gradient, Rectangle::new(quad.position.into(), quad.size.into()), ), quad, - }; - - self.gradients.push(quad); + }); Kind::Gradient } From 5fdc5affceca9345661ea2d213ccbce99721d09b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 30 May 2023 01:17:03 +0200 Subject: [PATCH 7/9] Rename `quad_order` variable to `kind` in `quad::Pipeline::render` --- wgpu/src/quad.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index 62472126b5..deb6d59ad4 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -113,8 +113,8 @@ impl Pipeline { let mut solid_offset = 0; let mut gradient_offset = 0; - for (quad_order, count) in &quads.order { - match quad_order { + for (kind, count) in &quads.order { + match kind { Kind::Solid => { render_pass.set_pipeline(&self.solid.pipeline); layer.solid.draw( From ef547469fdc8fe4faaa9902d9a8c920684f07189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 30 May 2023 01:33:50 +0200 Subject: [PATCH 8/9] Improve boundaries between `quad` submodules in `iced_wgpu` --- wgpu/src/quad.rs | 27 ++++++++------------ wgpu/src/quad/gradient.rs | 50 +++++++++++++++++++++++------------- wgpu/src/quad/solid.rs | 53 ++++++++++++++++++++++++--------------- 3 files changed, 75 insertions(+), 55 deletions(-) diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index deb6d59ad4..9c5ed05fca 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -116,21 +116,23 @@ impl Pipeline { for (kind, count) in &quads.order { match kind { Kind::Solid => { - render_pass.set_pipeline(&self.solid.pipeline); - layer.solid.draw( - &layer.constants, + self.solid.render( render_pass, + &layer.constants, + &layer.solid, solid_offset..(solid_offset + count), ); + solid_offset += count; } Kind::Gradient => { - render_pass.set_pipeline(&self.gradient.pipeline); - layer.gradient.draw( - &layer.constants, + self.gradient.render( render_pass, + &layer.constants, + &layer.gradient, gradient_offset..(gradient_offset + count), ); + gradient_offset += count; } } @@ -199,17 +201,8 @@ impl Layer { bytemuck::bytes_of(&uniforms), ); - let _ = self.solid.instances.resize(device, quads.solids.len()); - let _ = self - .gradient - .instances - .resize(device, quads.gradients.len()); - - let _ = self.solid.instances.write(queue, 0, &quads.solids); - let _ = self.gradient.instances.write(queue, 0, &quads.gradients); - - self.solid.instance_count = quads.solids.len(); - self.gradient.instance_count = quads.gradients.len(); + self.solid.prepare(device, queue, &quads.solids); + self.gradient.prepare(device, queue, &quads.gradients); } } diff --git a/wgpu/src/quad/gradient.rs b/wgpu/src/quad/gradient.rs index 2729afdf96..d3884ce1e2 100644 --- a/wgpu/src/quad/gradient.rs +++ b/wgpu/src/quad/gradient.rs @@ -24,13 +24,13 @@ unsafe impl Zeroable for Gradient {} #[derive(Debug)] pub struct Pipeline { - pub pipeline: wgpu::RenderPipeline, + pipeline: wgpu::RenderPipeline, } #[derive(Debug)] pub struct Layer { - pub instances: Buffer, - pub instance_count: usize, + instances: Buffer, + instance_count: usize, } impl Layer { @@ -48,23 +48,16 @@ impl Layer { } } - pub fn draw<'a>( - &'a self, - constants: &'a wgpu::BindGroup, - render_pass: &mut wgpu::RenderPass<'a>, - range: Range, + pub fn prepare( + &mut self, + device: &wgpu::Device, + queue: &wgpu::Queue, + instances: &[Gradient], ) { - #[cfg(feature = "tracing")] - let _ = tracing::info_span!("Wgpu::Quad::Gradient", "DRAW").entered(); - - render_pass.set_bind_group(0, constants, &[]); - render_pass.set_vertex_buffer(1, self.instances.slice(..)); + let _ = self.instances.resize(device, instances.len()); + let _ = self.instances.write(queue, 0, instances); - render_pass.draw_indexed( - 0..quad::INDICES.len() as u32, - 0, - range.start as u32..range.end as u32, - ); + self.instance_count = instances.len(); } } @@ -158,4 +151,25 @@ impl Pipeline { Self { pipeline } } + + pub fn render<'a>( + &'a self, + render_pass: &mut wgpu::RenderPass<'a>, + constants: &'a wgpu::BindGroup, + layer: &'a Layer, + range: Range, + ) { + #[cfg(feature = "tracing")] + let _ = tracing::info_span!("Wgpu::Quad::Gradient", "DRAW").entered(); + + render_pass.set_pipeline(&self.pipeline); + render_pass.set_bind_group(0, constants, &[]); + render_pass.set_vertex_buffer(1, layer.instances.slice(..)); + + render_pass.draw_indexed( + 0..quad::INDICES.len() as u32, + 0, + range.start as u32..range.end as u32, + ); + } } diff --git a/wgpu/src/quad/solid.rs b/wgpu/src/quad/solid.rs index 3540ce3a94..a3a7a0afac 100644 --- a/wgpu/src/quad/solid.rs +++ b/wgpu/src/quad/solid.rs @@ -17,13 +17,13 @@ pub struct Solid { #[derive(Debug)] pub struct Pipeline { - pub pipeline: wgpu::RenderPipeline, + pipeline: wgpu::RenderPipeline, } #[derive(Debug)] pub struct Layer { - pub instances: Buffer, - pub instance_count: usize, + instances: Buffer, + instance_count: usize, } impl Layer { @@ -41,23 +41,16 @@ impl Layer { } } - pub fn draw<'a>( - &'a self, - constants: &'a wgpu::BindGroup, - render_pass: &mut wgpu::RenderPass<'a>, - range: Range, + pub fn prepare( + &mut self, + device: &wgpu::Device, + queue: &wgpu::Queue, + instances: &[Solid], ) { - #[cfg(feature = "tracing")] - let _ = tracing::info_span!("Wgpu::Quad::Solid", "DRAW").entered(); - - render_pass.set_bind_group(0, constants, &[]); - render_pass.set_vertex_buffer(1, self.instances.slice(..)); + let _ = self.instances.resize(device, instances.len()); + let _ = self.instances.write(queue, 0, instances); - render_pass.draw_indexed( - 0..quad::INDICES.len() as u32, - 0, - range.start as u32..range.end as u32, - ); + self.instance_count = instances.len(); } } @@ -92,8 +85,7 @@ impl Pipeline { buffers: &[ quad::Vertex::buffer_layout(), wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::() - as u64, + array_stride: std::mem::size_of::() as u64, step_mode: wgpu::VertexStepMode::Instance, attributes: &wgpu::vertex_attr_array!( // Color @@ -133,4 +125,25 @@ impl Pipeline { Self { pipeline } } + + pub fn render<'a>( + &'a self, + render_pass: &mut wgpu::RenderPass<'a>, + constants: &'a wgpu::BindGroup, + layer: &'a Layer, + range: Range, + ) { + #[cfg(feature = "tracing")] + let _ = tracing::info_span!("Wgpu::Quad::Solid", "DRAW").entered(); + + render_pass.set_pipeline(&self.pipeline); + render_pass.set_bind_group(0, constants, &[]); + render_pass.set_vertex_buffer(1, layer.instances.slice(..)); + + render_pass.draw_indexed( + 0..quad::INDICES.len() as u32, + 0, + range.start as u32..range.end as u32, + ); + } } From c319f5113b274bedff0d18260eddbd6f9915efc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 30 May 2023 01:35:06 +0200 Subject: [PATCH 9/9] Move `Pipeline` struct definition after `Layer` in `quad` submodules --- wgpu/src/quad/gradient.rs | 10 +++++----- wgpu/src/quad/solid.rs | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/wgpu/src/quad/gradient.rs b/wgpu/src/quad/gradient.rs index d3884ce1e2..2b56d5942d 100644 --- a/wgpu/src/quad/gradient.rs +++ b/wgpu/src/quad/gradient.rs @@ -22,11 +22,6 @@ unsafe impl Pod for Gradient {} #[allow(unsafe_code)] unsafe impl Zeroable for Gradient {} -#[derive(Debug)] -pub struct Pipeline { - pipeline: wgpu::RenderPipeline, -} - #[derive(Debug)] pub struct Layer { instances: Buffer, @@ -61,6 +56,11 @@ impl Layer { } } +#[derive(Debug)] +pub struct Pipeline { + pipeline: wgpu::RenderPipeline, +} + impl Pipeline { pub fn new( device: &wgpu::Device, diff --git a/wgpu/src/quad/solid.rs b/wgpu/src/quad/solid.rs index a3a7a0afac..f667c42cd3 100644 --- a/wgpu/src/quad/solid.rs +++ b/wgpu/src/quad/solid.rs @@ -15,11 +15,6 @@ pub struct Solid { pub quad: Quad, } -#[derive(Debug)] -pub struct Pipeline { - pipeline: wgpu::RenderPipeline, -} - #[derive(Debug)] pub struct Layer { instances: Buffer, @@ -54,6 +49,11 @@ impl Layer { } } +#[derive(Debug)] +pub struct Pipeline { + pipeline: wgpu::RenderPipeline, +} + impl Pipeline { pub fn new( device: &wgpu::Device,