diff options
| author | 2023-05-30 00:56:52 +0200 | |
|---|---|---|
| committer | 2023-05-30 01:08:34 +0200 | |
| commit | fe9da174cafffbd77eb351c51ba017cf039a4cf4 (patch) | |
| tree | 0921ada9a8907ddfd46a360c21b0fd224d81216c /wgpu | |
| parent | eb6c663420a28e087c91c39e376db3c294b5aea1 (diff) | |
| download | iced-fe9da174cafffbd77eb351c51ba017cf039a4cf4.tar.gz iced-fe9da174cafffbd77eb351c51ba017cf039a4cf4.tar.bz2 iced-fe9da174cafffbd77eb351c51ba017cf039a4cf4.zip  | |
Move `layer::quad` types to `quad` module
Not sure why I split these to begin with!
Diffstat (limited to 'wgpu')
| -rw-r--r-- | wgpu/src/layer.rs | 7 | ||||
| -rw-r--r-- | wgpu/src/layer/quad.rs | 149 | ||||
| -rw-r--r-- | wgpu/src/quad.rs | 390 | ||||
| -rw-r--r-- | wgpu/src/quad/gradient.rs | 161 | ||||
| -rw-r--r-- | wgpu/src/quad/solid.rs | 136 | 
5 files changed, 408 insertions, 435 deletions
diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index 4e028eac..1a870c15 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<Mesh<'a>>, @@ -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 284a7618..00000000 --- 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<Solid>, - -    /// The gradient quads of the [`Layer`]. -    gradients: Vec<Gradient>, - -    /// 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 065da153..375b0cd7 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<u32>, -        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<quad::Solid>, -        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<usize>, -        ) { -            #[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<Solid>, -            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<Gradient>, -            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::<quad::Solid>() -                                    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<quad::Gradient>, -        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<usize>, -        ) { -            #[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<wgpu::ColorTargetState>; 1] { diff --git a/wgpu/src/quad/gradient.rs b/wgpu/src/quad/gradient.rs new file mode 100644 index 00000000..2729afdf --- /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<Gradient>, +    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<usize>, +    ) { +        #[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::<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: &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 00000000..3540ce3a --- /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<quad::Solid>, +    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<usize>, +    ) { +        #[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::<quad::Solid>() +                                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 } +    } +}  | 
