easy_gpu/assets/compute/
pipeline.rs1use 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 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("bind group 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 compute_uniform(binding: u32,) -> wgpu::BindGroupLayoutEntry {
66 wgpu::BindGroupLayoutEntry {
67 binding,
68 visibility: wgpu::ShaderStages::COMPUTE,
69 ty: wgpu::BindingType::Buffer {
70 ty: BufferBindingType::Uniform,
71 has_dynamic_offset: false,
72 min_binding_size: None,
73 },
74 count: None,
75 }
76}
77
78pub fn storage(binding: u32,read_only: bool) -> wgpu::BindGroupLayoutEntry {
79 wgpu::BindGroupLayoutEntry {
80 binding,
81 visibility: wgpu::ShaderStages::COMPUTE,
82 ty: wgpu::BindingType::Buffer {
83 ty: BufferBindingType::Storage { read_only },
84 has_dynamic_offset: false,
85 min_binding_size: None,
86 },
87 count: None,
88 }
89}
90
91pub fn storage_texture(binding: u32,format: TextureFormat) -> wgpu::BindGroupLayoutEntry {
92 wgpu::BindGroupLayoutEntry {
93 binding,
94 visibility: wgpu::ShaderStages::COMPUTE,
95 ty: wgpu::BindingType::StorageTexture {
96 access: StorageTextureAccess::WriteOnly,
97 format,
98 view_dimension: TextureViewDimension::D2,
99 },
100 count: None,
101 }
102}
103
104pub fn compute_texture_float(binding: u32) -> wgpu::BindGroupLayoutEntry {
105 wgpu::BindGroupLayoutEntry {
106 binding,
107 visibility: wgpu::ShaderStages::COMPUTE,
108 ty: wgpu::BindingType::Texture {
109 sample_type: wgpu::TextureSampleType::Float { filterable: true },
110 view_dimension: TextureViewDimension::D2,
111 multisampled: false,
112 },
113 count: None,
114 }
115}
116pub fn compute_texture_uint(binding: u32) -> wgpu::BindGroupLayoutEntry {
117 wgpu::BindGroupLayoutEntry {
118 binding,
119 visibility: wgpu::ShaderStages::COMPUTE,
120 ty: wgpu::BindingType::Texture {
121 sample_type: wgpu::TextureSampleType::Uint,
122 view_dimension: TextureViewDimension::D2,
123 multisampled: false,
124 },
125 count: None,
126 }
127}
128