# pipeline.rs - source
Source of the Rust file `maplibre/src/render/resource/pipeline.rs`.
Keywords: rust, rustlang, rust-lang

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89

    //! Utility for creating [RenderPipelines](wgpu::RenderPipeline)

    use crate::render::resource::shader::{FragmentState, VertexState};
    use std::borrow::Cow;

    pub trait RenderPipeline {
        fn describe_render_pipeline(self) -> RenderPipelineDescriptor;
    }

    pub struct RenderPipelineDescriptor {
        /// Debug label of the pipeline. This will show up in graphics debuggers for easy identification.
        pub label: Option<Cow<'static, str>>,
        /// The layout of bind groups for this pipeline.
        pub layout: Option<Vec<Vec<wgpu::BindGroupLayoutEntry>>>,
        /// The compiled vertex stage, its entry point, and the input buffers layout.
        pub vertex: VertexState,
        /// The properties of the pipeline at the primitive assembly and rasterization level.
        pub primitive: wgpu::PrimitiveState,
        /// The effect of draw calls on the depth and stencil aspects of the output target, if any.
        pub depth_stencil: Option<wgpu::DepthStencilState>,
        /// The multi-sampling properties of the pipeline.
        pub multisample: wgpu::MultisampleState,
        /// The compiled fragment stage, its entry point, and the color targets.
        pub fragment: FragmentState,
    }

    impl RenderPipelineDescriptor {
        pub fn initialize(&self, device: &wgpu::Device) -> wgpu::RenderPipeline {
            let bind_group_layouts = if let Some(layout) = &self.layout {
                layout
                    .iter()
                    .map(|entries| {
                        device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
                            label: None,
                            entries: entries.as_ref(),
                        })
                    })
                    .collect::<Vec<_>>()
            } else {
                vec![]
            };

            let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
                bind_group_layouts: &bind_group_layouts.iter().collect::<Vec<_>>(),
                ..Default::default()
            });

            let vertex_shader_module = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
                label: None,
                source: wgpu::ShaderSource::Wgsl(self.vertex.source.into()),
            });
            let fragment_shader_module = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
                label: None,
                source: wgpu::ShaderSource::Wgsl(self.fragment.source.into()),
            });

            let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
                label: self.label.as_ref().map(|label| label.as_ref()),
                layout: Some(&pipeline_layout),
                vertex: wgpu::VertexState {
                    module: &vertex_shader_module,
                    entry_point: self.vertex.entry_point,
                    buffers: self
                        .vertex
                        .buffers
                        .iter()
                        .map(|layout| wgpu::VertexBufferLayout {
                            array_stride: layout.array_stride,
                            step_mode: layout.step_mode,
                            attributes: layout.attributes.as_slice(),
                        })
                        .collect::<Vec<_>>()
                        .as_slice(),
                },
                fragment: Some(wgpu::FragmentState {
                    module: &fragment_shader_module,
                    entry_point: self.fragment.entry_point,
                    targets: self.fragment.targets.as_slice(),
                }),
                primitive: self.primitive,
                depth_stencil: self.depth_stencil.clone(),
                multisample: self.multisample,

                multiview: None,
            });

            pipeline
        }
    }