steamengine_renderer/
render_pipeline.rs1use std::num::NonZero;
2
3use wgpu::{PipelineCache, PipelineCompilationOptions, VertexBufferLayout};
4
5use super::Renderer;
6
7pub trait RenderPipeline {
9 fn label(&self) -> &str;
10 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 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, strip_index_format: None,
34 front_face: wgpu::FrontFace::Ccw, cull_mode: Some(wgpu::Face::Back),
36 polygon_mode: wgpu::PolygonMode::Fill,
38 unclipped_depth: false,
40 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}