summaryrefslogtreecommitdiffstats
path: root/wgpu/src/quad
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-05-30 00:56:52 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-05-30 01:08:34 +0200
commitfe9da174cafffbd77eb351c51ba017cf039a4cf4 (patch)
tree0921ada9a8907ddfd46a360c21b0fd224d81216c /wgpu/src/quad
parenteb6c663420a28e087c91c39e376db3c294b5aea1 (diff)
downloadiced-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/src/quad')
-rw-r--r--wgpu/src/quad/gradient.rs161
-rw-r--r--wgpu/src/quad/solid.rs136
2 files changed, 297 insertions, 0 deletions
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 }
+ }
+}