mraphics_core/render/
pipeline_manager.rs1use crate::{RenderInstance, constants::PrimitiveTopology};
2use std::collections::HashMap;
3
4pub struct PipelineManager {
5 pub pipeline_pool: HashMap<String, wgpu::RenderPipeline>,
6}
7
8impl PipelineManager {
9 pub fn new() -> Self {
10 Self {
11 pipeline_pool: HashMap::new(),
12 }
13 }
14
15 pub fn acquire_pipeline(
16 &mut self,
17 device: &wgpu::Device,
18 texture_format: wgpu::TextureFormat,
19 instance: &RenderInstance,
20 bind_groups: &[&wgpu::BindGroupLayout],
21 force_update: bool,
22 ) -> &wgpu::RenderPipeline {
23 let pipeline_identifier = format!(
24 "{}{}",
25 &instance.material.identifier,
26 instance.topology.to_str()
27 );
28
29 if !self.pipeline_pool.contains_key(&pipeline_identifier) || force_update {
30 self.insert_pipeline(
31 device,
32 texture_format,
33 instance,
34 bind_groups,
35 &pipeline_identifier,
36 );
37 }
38
39 &self.pipeline_pool.get(&pipeline_identifier).unwrap()
41 }
42
43 pub fn insert_pipeline(
44 &mut self,
45 device: &wgpu::Device,
46 texture_format: wgpu::TextureFormat,
47 instance: &RenderInstance,
48 bind_groups: &[&wgpu::BindGroupLayout],
49 pipeline_identifier: &String,
50 ) {
51 self.pipeline_pool.insert(
52 String::from(pipeline_identifier),
53 PipelineManager::build_pipeline(
54 device,
55 texture_format,
56 instance,
57 bind_groups,
58 instance.topology,
59 ),
60 );
61 }
62
63 pub fn build_pipeline(
64 device: &wgpu::Device,
65 texture_format: wgpu::TextureFormat,
66 instance: &RenderInstance,
67 bind_groups: &[&wgpu::BindGroupLayout],
68 topology: PrimitiveTopology,
69 ) -> wgpu::RenderPipeline {
70 let shader_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
71 label: Some("Mraphics Shader"),
72 source: wgpu::ShaderSource::Wgsl((&instance.material.shader_code).into()),
73 });
74
75 let render_pipeline_layout =
76 device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
77 label: Some("Mraphics Render Pipeline Layout"),
78 bind_group_layouts: bind_groups,
79 push_constant_ranges: &[],
80 });
81
82 let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
83 label: Some("Mraphics Render Pipeline"),
84 layout: Some(&render_pipeline_layout),
85 vertex: wgpu::VertexState {
86 module: &shader_module,
87 entry_point: Some("vs"),
88 buffers: &[],
89 compilation_options: wgpu::PipelineCompilationOptions::default(),
90 },
91 fragment: Some(wgpu::FragmentState {
92 module: &shader_module,
93 entry_point: Some("fs"),
94 targets: &[Some(wgpu::ColorTargetState {
95 format: texture_format,
96 blend: Some(wgpu::BlendState::REPLACE),
97 write_mask: wgpu::ColorWrites::ALL,
98 })],
99 compilation_options: wgpu::PipelineCompilationOptions::default(),
100 }),
101 primitive: wgpu::PrimitiveState {
102 topology: topology.to_wgpu(),
103 strip_index_format: None,
104 front_face: wgpu::FrontFace::Ccw,
105 cull_mode: None,
106 polygon_mode: wgpu::PolygonMode::Fill,
107 unclipped_depth: false,
108 conservative: false,
109 },
110 depth_stencil: None,
111 multisample: wgpu::MultisampleState::default(),
112 multiview: None,
113 cache: None,
114 });
115
116 render_pipeline
117 }
118}