pittore/render/render2d/
pipeline.rs1use glam::{Vec2, Vec4};
2
3use crate::{
4 backend::RenderState,
5 render::{bind_group::AsBindGroup, PipelineSet, PipelineSpec, PIPELINE_FILL},
6};
7
8use super::SpriteMaterial;
9
10pub const SHADER_2D_DEFAULT: u32 = 0;
11
12#[repr(C)]
13#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
14pub struct Vertex {
15 pub position: Vec2,
16 pub uv: Vec2,
17}
18
19#[repr(C)]
20#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
21pub struct Instance {
22 pub sprite_rect: Vec4,
23 pub matrix2: [f32; 4],
24 pub translation: Vec2,
25 pub color: [u8; 4],
26 pub _padding: [u8; 4],
27}
28
29pub struct PipelineBindGroup;
30
31impl AsBindGroup for PipelineBindGroup {
32 fn bind_group_layout(device: &wgpu::Device) -> wgpu::BindGroupLayout
33 where
34 Self: Sized,
35 {
36 device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
37 label: Some("fill_pipeline_bind_group_layout"),
38 entries: &[
39 wgpu::BindGroupLayoutEntry {
40 binding: 0,
41 visibility: wgpu::ShaderStages::VERTEX,
42 ty: wgpu::BindingType::Buffer {
43 ty: wgpu::BufferBindingType::Storage { read_only: true },
44 has_dynamic_offset: false,
45 min_binding_size: None,
46 },
47 count: None,
48 },
49 wgpu::BindGroupLayoutEntry {
50 binding: 1,
51 visibility: wgpu::ShaderStages::VERTEX,
52 ty: wgpu::BindingType::Buffer {
53 ty: wgpu::BufferBindingType::Storage { read_only: true },
54 has_dynamic_offset: false,
55 min_binding_size: None,
56 },
57 count: None,
58 },
59 ],
60 })
61 }
62
63 fn as_bind_group(&self, render_state: &RenderState) -> wgpu::BindGroup {
64 let buffers = &render_state.buffers;
65
66 render_state
67 .device
68 .create_bind_group(&wgpu::BindGroupDescriptor {
69 label: None,
70 layout: &Self::bind_group_layout(&render_state.device),
71 entries: &[
72 wgpu::BindGroupEntry {
73 binding: 0,
74 resource: buffers.get::<Vertex>().unwrap().as_entire_binding(),
75 },
76 wgpu::BindGroupEntry {
77 binding: 1,
78 resource: buffers.get::<Instance>().unwrap().as_entire_binding(),
79 },
80 ],
81 })
82 }
83}
84
85pub fn register_fill_pipeline(render_state: &mut RenderState) {
86 render_state.init_buffer::<Vertex>(wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST);
87 render_state
88 .init_buffer::<Instance>(wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST);
89
90 render_state.register_shader(SHADER_2D_DEFAULT, wgpu::include_wgsl!("shaders/fill.wgsl"));
91
92 let spec: PipelineSpec<PipelineBindGroup, SpriteMaterial> = PipelineSpec {
93 shader_id: SHADER_2D_DEFAULT,
94 ..Default::default()
95 };
96 let pipeline = spec.build(render_state);
97
98 let pipeline_set = PipelineSet {
99 pipeline,
100 pipeline_bind_group: Box::new(PipelineBindGroup),
101 };
102
103 render_state.pipelines.insert(PIPELINE_FILL, pipeline_set);
104}