steamengine_renderer/
render_pipeline.rs

1use std::num::NonZero;
2
3use wgpu::{PipelineCache, PipelineCompilationOptions, VertexBufferLayout};
4
5use super::Renderer;
6
7/// this trait is for create of render pipelines
8pub trait RenderPipeline {
9    fn label(&self) -> &str;
10    /// returns the shader code
11    fn source(&self) -> &str;
12    fn buffers(&self) -> Vec<VertexBufferLayout> {
13        vec![]
14    }
15    fn vertex_compilation(&self) -> PipelineCompilationOptions {
16        PipelineCompilationOptions::default()
17    }
18    fn targets<'a>(&self, renderer: &Renderer) -> Vec<Option<wgpu::ColorTargetState>> {
19        let format = renderer.config.read().unwrap().format.clone();
20        vec![Some(wgpu::ColorTargetState {
21            // 4.
22            format,
23            blend: Some(wgpu::BlendState::REPLACE),
24            write_mask: wgpu::ColorWrites::ALL,
25        })]
26    }
27    fn fragment_compilation(&self) -> PipelineCompilationOptions {
28        PipelineCompilationOptions::default()
29    }
30    fn primitive(&self) -> wgpu::PrimitiveState {
31        wgpu::PrimitiveState {
32            topology: wgpu::PrimitiveTopology::TriangleList, // 1.
33            strip_index_format: None,
34            front_face: wgpu::FrontFace::Ccw, // 2.
35            cull_mode: Some(wgpu::Face::Back),
36            // Setting this to anything other than Fill requires Features::NON_FILL_POLYGON_MODE
37            polygon_mode: wgpu::PolygonMode::Fill,
38            // Requires Features::DEPTH_CLIP_CONTROL
39            unclipped_depth: false,
40            // Requires Features::CONSERVATIVE_RASTERIZATION
41            conservative: false,
42        }
43    }
44    fn depth_stencil(&self) -> Option<wgpu::DepthStencilState> {
45        None
46    }
47    fn multisample(&self) -> wgpu::MultisampleState {
48        wgpu::MultisampleState {
49            count: 1,
50            mask: !0,
51            alpha_to_coverage_enabled: false,
52        }
53    }
54    fn multiview(&self) -> Option<NonZero<u32>> {
55        None
56    }
57    fn cache(&self) -> Option<&PipelineCache> {
58        None
59    }
60    fn layout(&self) -> wgpu::PipelineLayoutDescriptor {
61        wgpu::PipelineLayoutDescriptor {
62            label: Some("Render Pipeline Layout"),
63            bind_group_layouts: &[],
64            push_constant_ranges: &[],
65        }
66    }
67    fn to_wgpu<'a>(&self, renderer: &Renderer) -> wgpu::RenderPipeline {
68        let shader = renderer
69            .device()
70            .create_shader_module(wgpu::ShaderModuleDescriptor {
71                label: Some(format!("Shader Source of {}", self.label()).as_str()),
72                source: wgpu::ShaderSource::Wgsl(self.source().into()),
73            });
74        let layout = renderer.device().create_pipeline_layout(&self.layout());
75
76        let render_pipeline =
77            renderer
78                .device()
79                .create_render_pipeline(&wgpu::RenderPipelineDescriptor {
80                    label: Some(format!("Render Pipeline of {}", self.label()).as_str()),
81                    layout: Some(&layout),
82                    vertex: wgpu::VertexState {
83                        module: &shader,
84                        entry_point: Some("vs_main"),
85                        buffers: self.buffers().as_slice(),
86                        compilation_options: self.vertex_compilation(),
87                    },
88                    fragment: Some(wgpu::FragmentState {
89                        module: &shader,
90                        entry_point: Some("fs_main"),
91                        targets: self.targets(renderer).as_slice(),
92                        compilation_options: self.fragment_compilation(),
93                    }),
94                    primitive: self.primitive(),
95                    depth_stencil: self.depth_stencil(),
96                    multisample: self.multisample(),
97                    multiview: self.multiview(),
98                    cache: self.cache(),
99                });
100
101        render_pipeline
102    }
103}