tessera_ui_basic_components/pipelines/
mean.rs1use tessera_ui::{
20 compute::{ComputeResourceRef, resource::ComputeResourceManager},
21 renderer::compute::{ComputablePipeline, command::ComputeCommand},
22 wgpu,
23};
24
25#[derive(Debug, Clone, Copy)]
29pub struct MeanCommand {
37 result_buffer_ref: ComputeResourceRef,
38}
39
40impl MeanCommand {
41 pub fn new(gpu: &wgpu::Device, compute_resource_manager: &mut ComputeResourceManager) -> Self {
47 let result_buffer = gpu.create_buffer(&wgpu::BufferDescriptor {
48 label: Some("Mean Result Buffer"),
49 size: 8, usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_SRC,
51 mapped_at_creation: false,
52 });
53
54 let result_buffer_ref = compute_resource_manager.push(result_buffer);
55 MeanCommand { result_buffer_ref }
56 }
57
58 pub fn result_buffer_ref(&self) -> ComputeResourceRef {
60 self.result_buffer_ref
61 }
62}
63
64impl ComputeCommand for MeanCommand {}
65
66pub struct MeanPipeline {
76 pipeline: wgpu::ComputePipeline,
77 bind_group_layout: wgpu::BindGroupLayout,
78}
79
80impl MeanPipeline {
81 pub fn new(device: &wgpu::Device) -> Self {
82 let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
83 label: Some("Mean Shader"),
84 source: wgpu::ShaderSource::Wgsl(include_str!("mean/mean.wgsl").into()),
85 });
86
87 let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
88 entries: &[
89 wgpu::BindGroupLayoutEntry {
91 binding: 0,
92 visibility: wgpu::ShaderStages::COMPUTE,
93 ty: wgpu::BindingType::Texture {
94 sample_type: wgpu::TextureSampleType::Float { filterable: false },
95 view_dimension: wgpu::TextureViewDimension::D2,
96 multisampled: false,
97 },
98 count: None,
99 },
100 wgpu::BindGroupLayoutEntry {
102 binding: 1,
103 visibility: wgpu::ShaderStages::COMPUTE,
104 ty: wgpu::BindingType::Buffer {
105 ty: wgpu::BufferBindingType::Storage { read_only: false },
106 has_dynamic_offset: false,
107 min_binding_size: Some(std::num::NonZeroU64::new(8).unwrap()),
108 },
109 count: None,
110 },
111 wgpu::BindGroupLayoutEntry {
113 binding: 2,
114 visibility: wgpu::ShaderStages::COMPUTE,
115 ty: wgpu::BindingType::StorageTexture {
116 access: wgpu::StorageTextureAccess::WriteOnly,
117 format: wgpu::TextureFormat::Rgba8Unorm,
118 view_dimension: wgpu::TextureViewDimension::D2,
119 },
120 count: None,
121 },
122 ],
123 label: Some("mean_bind_group_layout"),
124 });
125
126 let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
127 label: Some("Mean Pipeline Layout"),
128 bind_group_layouts: &[&bind_group_layout],
129 push_constant_ranges: &[],
130 });
131
132 let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
133 label: Some("Mean Pipeline"),
134 layout: Some(&pipeline_layout),
135 module: &shader,
136 entry_point: Some("main"),
137 compilation_options: Default::default(),
138 cache: None,
139 });
140
141 Self {
142 pipeline,
143 bind_group_layout,
144 }
145 }
146}
147
148impl ComputablePipeline<MeanCommand> for MeanPipeline {
149 fn dispatch(
160 &mut self,
161 device: &wgpu::Device,
162 _queue: &wgpu::Queue,
163 config: &wgpu::SurfaceConfiguration,
164 compute_pass: &mut wgpu::ComputePass<'_>,
165 command: &MeanCommand,
166 resource_manager: &mut ComputeResourceManager,
167 input_view: &wgpu::TextureView,
168 output_view: &wgpu::TextureView,
169 ) {
170 let result_buffer = resource_manager.get(&command.result_buffer_ref).unwrap();
171 let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
172 layout: &self.bind_group_layout,
173 entries: &[
174 wgpu::BindGroupEntry {
175 binding: 0,
176 resource: wgpu::BindingResource::TextureView(input_view),
177 },
178 wgpu::BindGroupEntry {
179 binding: 1,
180 resource: result_buffer.as_entire_binding(),
181 },
182 wgpu::BindGroupEntry {
183 binding: 2,
184 resource: wgpu::BindingResource::TextureView(output_view),
185 },
186 ],
187 label: Some("mean_bind_group"),
188 });
189
190 compute_pass.set_pipeline(&self.pipeline);
191 compute_pass.set_bind_group(0, &bind_group, &[]);
192 compute_pass.dispatch_workgroups(config.width.div_ceil(8), config.height.div_ceil(8), 1);
193 }
194}