Skip to content

Commit 8128b1b

Browse files
committed
render: factor post bind-group rebuild and fullscreen blit helper; replace repeated passes with helper calls
1 parent fb85d96 commit 8128b1b

File tree

2 files changed

+164
-162
lines changed

2 files changed

+164
-162
lines changed

crates/app-web/src/render.rs

Lines changed: 161 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -673,88 +673,7 @@ impl<'a> GpuState<'a> {
673673
.create_view(&wgpu::TextureViewDescriptor::default());
674674

675675
// Rebuild bind groups that reference these views
676-
self.bg_hdr = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
677-
label: Some("bg_hdr"),
678-
layout: &self.post_bgl0,
679-
entries: &[
680-
wgpu::BindGroupEntry {
681-
binding: 0,
682-
resource: wgpu::BindingResource::TextureView(&self.hdr_view),
683-
},
684-
wgpu::BindGroupEntry {
685-
binding: 1,
686-
resource: wgpu::BindingResource::Sampler(&self.linear_sampler),
687-
},
688-
wgpu::BindGroupEntry {
689-
binding: 2,
690-
resource: self.post_uniform_buffer.as_entire_binding(),
691-
},
692-
],
693-
});
694-
self.bg_from_bloom_a = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
695-
label: Some("bg_from_bloom_a"),
696-
layout: &self.post_bgl0,
697-
entries: &[
698-
wgpu::BindGroupEntry {
699-
binding: 0,
700-
resource: wgpu::BindingResource::TextureView(&self.bloom_a_view),
701-
},
702-
wgpu::BindGroupEntry {
703-
binding: 1,
704-
resource: wgpu::BindingResource::Sampler(&self.linear_sampler),
705-
},
706-
wgpu::BindGroupEntry {
707-
binding: 2,
708-
resource: self.post_uniform_buffer.as_entire_binding(),
709-
},
710-
],
711-
});
712-
self.bg_from_bloom_b = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
713-
label: Some("bg_from_bloom_b"),
714-
layout: &self.post_bgl0,
715-
entries: &[
716-
wgpu::BindGroupEntry {
717-
binding: 0,
718-
resource: wgpu::BindingResource::TextureView(&self.bloom_b_view),
719-
},
720-
wgpu::BindGroupEntry {
721-
binding: 1,
722-
resource: wgpu::BindingResource::Sampler(&self.linear_sampler),
723-
},
724-
wgpu::BindGroupEntry {
725-
binding: 2,
726-
resource: self.post_uniform_buffer.as_entire_binding(),
727-
},
728-
],
729-
});
730-
self.bg_bloom_a_only = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
731-
label: Some("bg_bloom_a_only"),
732-
layout: &self.post_bgl1,
733-
entries: &[
734-
wgpu::BindGroupEntry {
735-
binding: 0,
736-
resource: wgpu::BindingResource::TextureView(&self.bloom_a_view),
737-
},
738-
wgpu::BindGroupEntry {
739-
binding: 1,
740-
resource: wgpu::BindingResource::Sampler(&self.linear_sampler),
741-
},
742-
],
743-
});
744-
self.bg_bloom_b_only = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
745-
label: Some("bg_bloom_b_only"),
746-
layout: &self.post_bgl1,
747-
entries: &[
748-
wgpu::BindGroupEntry {
749-
binding: 0,
750-
resource: wgpu::BindingResource::TextureView(&self.bloom_b_view),
751-
},
752-
wgpu::BindGroupEntry {
753-
binding: 1,
754-
resource: wgpu::BindingResource::Sampler(&self.linear_sampler),
755-
},
756-
],
757-
});
676+
self.rebuild_post_bind_groups();
758677
}
759678
}
760679

@@ -834,101 +753,184 @@ impl<'a> GpuState<'a> {
834753
.write_buffer(&self.post_uniform_buffer, 0, bytemuck::bytes_of(&post));
835754

836755
// Pass 2: bright pass → bloom_a
837-
{
838-
let mut r = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
839-
label: Some("bright_pass"),
840-
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
841-
view: &self.bloom_a_view,
842-
resolve_target: None,
843-
ops: wgpu::Operations {
844-
load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
845-
store: wgpu::StoreOp::Store,
846-
},
847-
})],
848-
depth_stencil_attachment: None,
849-
timestamp_writes: None,
850-
occlusion_query_set: None,
851-
});
852-
r.set_pipeline(&self.bright_pipeline);
853-
r.set_bind_group(0, &self.bg_hdr, &[]);
854-
r.draw(0..3, 0..1);
855-
}
756+
self.blit(
757+
&mut encoder,
758+
"bright_pass",
759+
&self.bloom_a_view,
760+
wgpu::Color::BLACK,
761+
&self.bright_pipeline,
762+
&self.bg_hdr,
763+
None,
764+
);
856765

857766
// Pass 3: blur horizontal bloom_a -> bloom_b
858767
post.blur_dir = [1.0, 0.0];
859768
self.queue
860769
.write_buffer(&self.post_uniform_buffer, 0, bytemuck::bytes_of(&post));
861-
{
862-
let mut r = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
863-
label: Some("blur_h"),
864-
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
865-
view: &self.bloom_b_view,
866-
resolve_target: None,
867-
ops: wgpu::Operations {
868-
load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
869-
store: wgpu::StoreOp::Store,
870-
},
871-
})],
872-
depth_stencil_attachment: None,
873-
timestamp_writes: None,
874-
occlusion_query_set: None,
875-
});
876-
r.set_pipeline(&self.blur_pipeline);
877-
r.set_bind_group(0, &self.bg_from_bloom_a, &[]);
878-
r.draw(0..3, 0..1);
879-
}
770+
self.blit(
771+
&mut encoder,
772+
"blur_h",
773+
&self.bloom_b_view,
774+
wgpu::Color::BLACK,
775+
&self.blur_pipeline,
776+
&self.bg_from_bloom_a,
777+
None,
778+
);
880779

881780
// Pass 4: blur vertical bloom_b -> bloom_a
882781
post.blur_dir = [0.0, 1.0];
883782
self.queue
884783
.write_buffer(&self.post_uniform_buffer, 0, bytemuck::bytes_of(&post));
885-
{
886-
let mut r = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
887-
label: Some("blur_v"),
888-
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
889-
view: &self.bloom_a_view,
890-
resolve_target: None,
891-
ops: wgpu::Operations {
892-
load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
893-
store: wgpu::StoreOp::Store,
894-
},
895-
})],
896-
depth_stencil_attachment: None,
897-
timestamp_writes: None,
898-
occlusion_query_set: None,
899-
});
900-
r.set_pipeline(&self.blur_pipeline);
901-
r.set_bind_group(0, &self.bg_from_bloom_b, &[]);
902-
r.draw(0..3, 0..1);
903-
}
784+
self.blit(
785+
&mut encoder,
786+
"blur_v",
787+
&self.bloom_a_view,
788+
wgpu::Color::BLACK,
789+
&self.blur_pipeline,
790+
&self.bg_from_bloom_b,
791+
None,
792+
);
904793

905794
// Pass 5: composite to swapchain
906795
post.blur_dir = [0.0, 0.0];
907796
self.queue
908797
.write_buffer(&self.post_uniform_buffer, 0, bytemuck::bytes_of(&post));
909-
{
910-
let mut r = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
911-
label: Some("composite"),
912-
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
913-
view: &view,
914-
resolve_target: None,
915-
ops: wgpu::Operations {
916-
load: wgpu::LoadOp::Clear(self.clear_color),
917-
store: wgpu::StoreOp::Store,
918-
},
919-
})],
920-
depth_stencil_attachment: None,
921-
timestamp_writes: None,
922-
occlusion_query_set: None,
923-
});
924-
r.set_pipeline(&self.composite_pipeline);
925-
r.set_bind_group(0, &self.bg_hdr, &[]);
926-
r.set_bind_group(1, &self.bg_bloom_a_only, &[]);
927-
r.draw(0..3, 0..1);
928-
}
798+
self.blit(
799+
&mut encoder,
800+
"composite",
801+
&view,
802+
self.clear_color,
803+
&self.composite_pipeline,
804+
&self.bg_hdr,
805+
Some(&self.bg_bloom_a_only),
806+
);
929807

930808
self.queue.submit(Some(encoder.finish()));
931809
frame.present();
932810
Ok(())
933811
}
934812
}
813+
814+
impl<'a> GpuState<'a> {
815+
fn rebuild_post_bind_groups(&mut self) {
816+
// bg sampling HDR scene
817+
self.bg_hdr = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
818+
label: Some("bg_hdr"),
819+
layout: &self.post_bgl0,
820+
entries: &[
821+
wgpu::BindGroupEntry {
822+
binding: 0,
823+
resource: wgpu::BindingResource::TextureView(&self.hdr_view),
824+
},
825+
wgpu::BindGroupEntry {
826+
binding: 1,
827+
resource: wgpu::BindingResource::Sampler(&self.linear_sampler),
828+
},
829+
wgpu::BindGroupEntry {
830+
binding: 2,
831+
resource: self.post_uniform_buffer.as_entire_binding(),
832+
},
833+
],
834+
});
835+
// bg sampling bloom_a
836+
self.bg_from_bloom_a = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
837+
label: Some("bg_from_bloom_a"),
838+
layout: &self.post_bgl0,
839+
entries: &[
840+
wgpu::BindGroupEntry {
841+
binding: 0,
842+
resource: wgpu::BindingResource::TextureView(&self.bloom_a_view),
843+
},
844+
wgpu::BindGroupEntry {
845+
binding: 1,
846+
resource: wgpu::BindingResource::Sampler(&self.linear_sampler),
847+
},
848+
wgpu::BindGroupEntry {
849+
binding: 2,
850+
resource: self.post_uniform_buffer.as_entire_binding(),
851+
},
852+
],
853+
});
854+
// bg sampling bloom_b
855+
self.bg_from_bloom_b = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
856+
label: Some("bg_from_bloom_b"),
857+
layout: &self.post_bgl0,
858+
entries: &[
859+
wgpu::BindGroupEntry {
860+
binding: 0,
861+
resource: wgpu::BindingResource::TextureView(&self.bloom_b_view),
862+
},
863+
wgpu::BindGroupEntry {
864+
binding: 1,
865+
resource: wgpu::BindingResource::Sampler(&self.linear_sampler),
866+
},
867+
wgpu::BindGroupEntry {
868+
binding: 2,
869+
resource: self.post_uniform_buffer.as_entire_binding(),
870+
},
871+
],
872+
});
873+
// group1 variants (no uniforms)
874+
self.bg_bloom_a_only = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
875+
label: Some("bg_bloom_a_only"),
876+
layout: &self.post_bgl1,
877+
entries: &[
878+
wgpu::BindGroupEntry {
879+
binding: 0,
880+
resource: wgpu::BindingResource::TextureView(&self.bloom_a_view),
881+
},
882+
wgpu::BindGroupEntry {
883+
binding: 1,
884+
resource: wgpu::BindingResource::Sampler(&self.linear_sampler),
885+
},
886+
],
887+
});
888+
self.bg_bloom_b_only = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
889+
label: Some("bg_bloom_b_only"),
890+
layout: &self.post_bgl1,
891+
entries: &[
892+
wgpu::BindGroupEntry {
893+
binding: 0,
894+
resource: wgpu::BindingResource::TextureView(&self.bloom_b_view),
895+
},
896+
wgpu::BindGroupEntry {
897+
binding: 1,
898+
resource: wgpu::BindingResource::Sampler(&self.linear_sampler),
899+
},
900+
],
901+
});
902+
}
903+
904+
fn blit(
905+
&self,
906+
encoder: &mut wgpu::CommandEncoder,
907+
label: &str,
908+
target: &wgpu::TextureView,
909+
clear: wgpu::Color,
910+
pipeline: &wgpu::RenderPipeline,
911+
bg0: &wgpu::BindGroup,
912+
bg1: Option<&wgpu::BindGroup>,
913+
) {
914+
let mut r = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
915+
label: Some(label),
916+
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
917+
view: target,
918+
resolve_target: None,
919+
ops: wgpu::Operations {
920+
load: wgpu::LoadOp::Clear(clear),
921+
store: wgpu::StoreOp::Store,
922+
},
923+
})],
924+
depth_stencil_attachment: None,
925+
timestamp_writes: None,
926+
occlusion_query_set: None,
927+
});
928+
r.set_pipeline(pipeline);
929+
r.set_bind_group(0, bg0, &[]);
930+
if let Some(g1) = bg1 {
931+
r.set_bind_group(1, g1, &[]);
932+
}
933+
r.draw(0..3, 0..1);
934+
drop(r);
935+
}
936+
}

docs/TODO.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ Desktop UI support has been removed to simplify the project and focus on the web
124124
- [ ] app-web: extract WebGPU pipeline builders
125125
- Rationale: deduplicate pipeline/buffer setup for waves/post passes
126126
- Plan: create `pipeline.rs` helpers returning typed bundles; no functional changes
127-
- [x] app-web: deduplicate pointer event wiring
128-
- Rationale: avoid drift by handling `pointermove`/drag/hover in one place (`events::wire_input_handlers`)
129-
- Impact: removed duplicate handler from `lib.rs`; behavior unchanged
127+
- [x] app-web: deduplicate pointer event wiring
128+
- Rationale: avoid drift by handling `pointermove`/drag/hover in one place (`events::wire_input_handlers`)
129+
- Impact: removed duplicate handler from `lib.rs`; behavior unchanged
130130

131131
### Testing Enhancements
132132

0 commit comments

Comments
 (0)