Skip to main content

easy_gpu/assets/compute/
pipeline.rs

1use wgpu::{BindGroupLayout, BufferBindingType, ComputePipelineDescriptor, ShaderModule, StorageTextureAccess, TextureFormat, TextureViewDimension};
2use crate::assets_manager::Handle;
3use crate::Renderer;
4
5pub struct ComputePipeline{
6    pub pipeline: wgpu::ComputePipeline,
7    pub layout: BindGroupLayout,
8}
9
10pub struct ComputePipelineBuilder<'a>{
11    shader: Handle<ShaderModule>,
12    entries: Vec<wgpu::BindGroupLayoutEntry>,
13    entry_point: &'a str,
14}
15
16impl<'a> ComputePipelineBuilder<'a>{
17    pub fn new(shader: Handle<ShaderModule>)->Self{
18        Self{
19            shader,
20            entries: vec![],
21            entry_point: "cs_main"
22        }
23    }
24    pub fn entry_point(mut self, entry_point: &'a str)->Self{
25        self.entry_point = entry_point;
26        self
27    }
28    pub fn bind_group_layout(
29        mut self,
30        entries: &[wgpu::BindGroupLayoutEntry],
31    ) -> Self {
32        self.entries = entries.to_vec();
33        self
34    }
35    pub(crate) fn build(self,renderer: &mut Renderer) -> Handle<ComputePipeline>{
36        let bind_group_layout = renderer.device.create_bind_group_layout(
37            &wgpu::BindGroupLayoutDescriptor {
38                label: Some("material layout"),
39                entries: &self.entries,
40            }
41        );
42        
43        let layout = renderer.device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor{
44            label: None,
45            bind_group_layouts: &[Some(&bind_group_layout)],
46            immediate_size: 0,
47        });
48
49        let pipeline = renderer.device.create_compute_pipeline(&ComputePipelineDescriptor{
50            label: Some("Compute Pipeline"),
51            layout: Some(&layout),
52            module: renderer.asset_manager.shaders.get(self.shader).unwrap(),
53            entry_point: Some(self.entry_point),
54            compilation_options: Default::default(),
55            cache: None,
56        });
57
58        renderer.asset_manager.compute_pipelines.insert(ComputePipeline{
59            pipeline,
60            layout: bind_group_layout,
61        })
62    }
63}
64
65pub fn storage(binding: u32,read_only: bool) -> wgpu::BindGroupLayoutEntry {
66    wgpu::BindGroupLayoutEntry {
67        binding,
68        visibility: wgpu::ShaderStages::COMPUTE,
69        ty: wgpu::BindingType::Buffer {
70            ty: BufferBindingType::Storage { read_only },
71            has_dynamic_offset: false,
72            min_binding_size: None,
73        },
74        count: None,
75    }
76}
77
78pub fn storage_texture(binding: u32) -> wgpu::BindGroupLayoutEntry {
79    wgpu::BindGroupLayoutEntry {
80        binding,
81        visibility: wgpu::ShaderStages::COMPUTE,
82        ty: wgpu::BindingType::StorageTexture {
83            access: StorageTextureAccess::WriteOnly,
84            format: TextureFormat::Rgba8Unorm,
85            view_dimension: TextureViewDimension::D2,
86        },
87        count: None,
88    }
89}
90
91/*pub fn texture(binding: u32) -> wgpu::BindGroupLayoutEntry {
92    wgpu::BindGroupLayoutEntry {
93        binding,
94        visibility: wgpu::ShaderStages::COMPUTE,
95        ty: wgpu::BindingType::Texture {
96            sample_type: wgpu::TextureSampleType::Float { filterable: true },
97            view_dimension: TextureViewDimension::D2,
98            multisampled: false,
99        },
100        count: None,
101    }
102}*/
103