iced_wgpu/quad/
solid.rs
1use crate::Buffer;
2use crate::graphics::color;
3use crate::quad::{self, Quad};
4
5use bytemuck::{Pod, Zeroable};
6use std::ops::Range;
7
8#[derive(Clone, Copy, Debug, Pod, Zeroable)]
10#[repr(C)]
11pub struct Solid {
12 pub color: color::Packed,
14
15 pub quad: Quad,
17}
18
19#[derive(Debug)]
20pub struct Layer {
21 instances: Buffer<Solid>,
22 instance_count: usize,
23}
24
25impl Layer {
26 pub fn new(device: &wgpu::Device) -> Self {
27 let instances = Buffer::new(
28 device,
29 "iced_wgpu.quad.solid.buffer",
30 quad::INITIAL_INSTANCES,
31 wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
32 );
33
34 Self {
35 instances,
36 instance_count: 0,
37 }
38 }
39
40 pub fn prepare(
41 &mut self,
42 device: &wgpu::Device,
43 encoder: &mut wgpu::CommandEncoder,
44 belt: &mut wgpu::util::StagingBelt,
45 instances: &[Solid],
46 ) {
47 let _ = self.instances.resize(device, instances.len());
48 let _ = self.instances.write(device, encoder, belt, 0, instances);
49
50 self.instance_count = instances.len();
51 }
52}
53
54#[derive(Debug)]
55pub struct Pipeline {
56 pipeline: wgpu::RenderPipeline,
57}
58
59impl Pipeline {
60 pub fn new(
61 device: &wgpu::Device,
62 format: wgpu::TextureFormat,
63 constants_layout: &wgpu::BindGroupLayout,
64 ) -> Self {
65 let layout =
66 device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
67 label: Some("iced_wgpu.quad.solid.pipeline"),
68 push_constant_ranges: &[],
69 bind_group_layouts: &[constants_layout],
70 });
71
72 let shader =
73 device.create_shader_module(wgpu::ShaderModuleDescriptor {
74 label: Some("iced_wgpu.quad.solid.shader"),
75 source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
76 concat!(
77 include_str!("../shader/quad.wgsl"),
78 "\n",
79 include_str!("../shader/vertex.wgsl"),
80 "\n",
81 include_str!("../shader/quad/solid.wgsl"),
82 ),
83 )),
84 });
85
86 let pipeline =
87 device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
88 label: Some("iced_wgpu.quad.solid.pipeline"),
89 layout: Some(&layout),
90 vertex: wgpu::VertexState {
91 module: &shader,
92 entry_point: Some("solid_vs_main"),
93 buffers: &[wgpu::VertexBufferLayout {
94 array_stride: std::mem::size_of::<Solid>() as u64,
95 step_mode: wgpu::VertexStepMode::Instance,
96 attributes: &wgpu::vertex_attr_array!(
97 0 => Float32x4,
99 1 => Float32x2,
101 2 => Float32x2,
103 3 => Float32x4,
105 4 => Float32x4,
107 5 => Float32,
109 6 => Float32x4,
111 7 => Float32x2,
113 8 => Float32,
115 ),
116 }],
117 compilation_options:
118 wgpu::PipelineCompilationOptions::default(),
119 },
120 fragment: Some(wgpu::FragmentState {
121 module: &shader,
122 entry_point: Some("solid_fs_main"),
123 targets: &quad::color_target_state(format),
124 compilation_options:
125 wgpu::PipelineCompilationOptions::default(),
126 }),
127 primitive: wgpu::PrimitiveState {
128 topology: wgpu::PrimitiveTopology::TriangleList,
129 front_face: wgpu::FrontFace::Cw,
130 ..Default::default()
131 },
132 depth_stencil: None,
133 multisample: wgpu::MultisampleState {
134 count: 1,
135 mask: !0,
136 alpha_to_coverage_enabled: false,
137 },
138 multiview: None,
139 cache: None,
140 });
141
142 Self { pipeline }
143 }
144
145 pub fn render<'a>(
146 &'a self,
147 render_pass: &mut wgpu::RenderPass<'a>,
148 constants: &'a wgpu::BindGroup,
149 layer: &'a Layer,
150 range: Range<usize>,
151 ) {
152 render_pass.set_pipeline(&self.pipeline);
153 render_pass.set_bind_group(0, constants, &[]);
154 render_pass.set_vertex_buffer(0, layer.instances.slice(..));
155
156 render_pass.draw(0..6, range.start as u32..range.end as u32);
157 }
158}