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 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
91pub fn compute_texture_float(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}
103pub fn compute_texture_uint(binding: u32) -> wgpu::BindGroupLayoutEntry {
104 wgpu::BindGroupLayoutEntry {
105 binding,
106 visibility: wgpu::ShaderStages::COMPUTE,
107 ty: wgpu::BindingType::Texture {
108 sample_type: wgpu::TextureSampleType::Uint,
109 view_dimension: TextureViewDimension::D2,
110 multisampled: false,
111 },
112 count: None,
113 }
114}
115