Skip to content

Commit

Permalink
gpu: Small preparations for using fewer submissions.
Browse files Browse the repository at this point in the history
None are actually eliminated, but there are notes about why not,
and more functions return command buffers instead of submitting them.
  • Loading branch information
kpreid committed Jan 10, 2025
1 parent 3702366 commit a337a63
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 14 deletions.
16 changes: 10 additions & 6 deletions all-is-cubes-gpu/src/in_wgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,16 +242,18 @@ impl<I: time::Instant> SurfaceRenderer<I> {
};

// Render info and postprocessing step.
// TODO: We should record the amount of time this takes, then display that
// next frame.
info.flaws |= self.everything.add_info_text_and_postprocess(
// TODO: We should record the amount of time this takes, then display that next frame.
// TODO(efficiency): combine draw_frame_linear and postprocess into one submission.
let (post_cmd, post_flaws) = self.everything.add_info_text_and_postprocess(
&self.queue,
&output.texture.create_view(&TextureViewDescriptor {
format: Some(surface_view_format(self.everything.config.format)),
..Default::default()
}),
&info_text_fn(&info),
);
info.flaws |= post_flaws;
self.queue.submit([post_cmd]);
output.present();
Ok(info)
}
Expand Down Expand Up @@ -840,6 +842,8 @@ impl<I: time::Instant> EverythingRenderer<I> {

// let postprocess_to_submit_time = Instant::now();

// TODO(efficiency): allow this submit to happen externally and be combined with others
// (postprocessing, in particular).
queue.submit(std::iter::once(encoder.finish()));
self.staging_belt.recall();

Expand All @@ -864,7 +868,7 @@ impl<I: time::Instant> EverythingRenderer<I> {
queue: &wgpu::Queue,
output: &wgpu::TextureView,
mut text: &str,
) -> Flaws {
) -> (wgpu::CommandBuffer, Flaws) {
// Apply info text option
if !self.cameras.cameras().world.options().debug_info_text {
text = "";
Expand All @@ -880,12 +884,12 @@ impl<I: time::Instant> EverythingRenderer<I> {
info_text_texture.upload(queue);
}

let flaws = postprocess::postprocess(self, queue, output);
let (postprocess_cmd, flaws) = postprocess::postprocess(self, output);

#[cfg(feature = "rerun")]
self.rerun_image.finish_frame();

flaws
(postprocess_cmd, flaws)
}

/// Activate logging performance information to a Rerun stream.
Expand Down
5 changes: 5 additions & 0 deletions all-is-cubes-gpu/src/in_wgpu/block_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,9 @@ impl AllocatorBacking {
device: &wgpu::Device,
queue: &wgpu::Queue,
) -> (Group<Arc<Identified<wgpu::TextureView>>>, BlockTextureInfo) {
// TODO: Consider replacing all the queued texture writes and copies with `StagingBelt`.
// Will need to teach `StagingBelt` about copying to textures.

let mut backing_lock_guard = backing_mutex.lock().unwrap();
let backing = &mut *backing_lock_guard;

Expand Down Expand Up @@ -486,6 +489,8 @@ impl AllocatorBacking {
copy(&mut encoder, oe, ne);
}

// TODO(efficiency): Eliminate this separated submit, without breaking things
// by reordering the copy_texture_to_texture() after the following write_texture()s.
queue.submit([encoder.finish()]);
}

Expand Down
3 changes: 2 additions & 1 deletion all-is-cubes-gpu/src/in_wgpu/headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,14 @@ impl RendererImpl {
}

let draw_info = self.everything.draw_frame_linear(&self.queue);
let post_flaws = self.everything.add_info_text_and_postprocess(
let (post_cmd, post_flaws) = self.everything.add_info_text_and_postprocess(
&self.queue,
&self
.color_texture
.create_view(&wgpu::TextureViewDescriptor::default()),
info_text,
);
self.queue.submit([post_cmd]);
let image = init::get_image_from_gpu(
&self.device,
&self.queue,
Expand Down
6 changes: 5 additions & 1 deletion all-is-cubes-gpu/src/in_wgpu/light_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,10 +484,14 @@ impl LightTexture {
total_count += 1;
}

// TODO: use `StagingBelt` to write buffer instead.
// TODO(efficiency): use `StagingBelt` to write buffer instead.
// To do this optimally, `StagingBelt` will need to be modified to allow
// us accessing its buffers to issue a `copy_buffer_to_texture` instead of
// it issuing a `copy_buffer_to_buffer`.
//
// It should be worth it, though, as I am informed that `submit()`ing repeatedly
// is costly, and by avoiding `write_buffer()` we can just use a single command
// buffer.
queue.write_buffer(
&self.copy_buffer,
0,
Expand Down
9 changes: 3 additions & 6 deletions all-is-cubes-gpu/src/in_wgpu/postprocess.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,8 @@ impl PostprocessUniforms {
pub(crate) fn postprocess<I: time::Instant>(
// TODO: instead of accepting `EverythingRenderer`, pass smaller (but not too numerous) things
ev: &mut super::EverythingRenderer<I>,
queue: &wgpu::Queue,
output: &wgpu::TextureView,
) -> Flaws {
) -> (wgpu::CommandBuffer, Flaws) {
let mut encoder = ev
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
Expand All @@ -173,7 +172,7 @@ pub(crate) fn postprocess<I: time::Instant>(

let Some(postprocess_render_pipeline) = ev.postprocess_render_pipeline.get() else {
// This shouldn't happen, but if it does, don't panic.
return Flaws::UNFINISHED;
return (encoder.finish(), Flaws::UNFINISHED);
};

// Render pass
Expand Down Expand Up @@ -239,7 +238,5 @@ pub(crate) fn postprocess<I: time::Instant>(
render_pass.draw(0..3, 0..1);
}

queue.submit(std::iter::once(encoder.finish()));

Flaws::empty()
(encoder.finish(), Flaws::empty())
}

0 comments on commit a337a63

Please sign in to comment.