Skip to content

Commit

Permalink
gpu: Add background meshing tasks.
Browse files Browse the repository at this point in the history
This seems to introduce a hiccup on desktop (but not wasm) startup,
just when the second frame should be getting rendered, more or less.
I'm not sure what is going on and the self-profiling info doesn't
reveal anything that shouldn't be happening; the `render_data_updater`
calls for blocks are taking a _little_ unreasonable amount of time,
but 250 ms, not multiple seconds, so that's not it.
  • Loading branch information
kpreid committed Feb 14, 2024
1 parent 161523d commit b6e2761
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 5 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ re_log_types = { version = "0.13.0", default-features = false }
re_sdk = { version = "0.13.0", default-features = false }
re_types = { version = "0.13.0", default-features = false }
rendiff = { version = "0.1.0" }
send_wrapper = "0.6.0"
send_wrapper = { version = "0.6.0", features = ["futures"] }
serde = { version = "1.0.160", default-features = false, features = ["derive"] }
serde_json = "1.0.79"
simplelog = { version = "0.12.0", default-features = false, features = ["local-offset"] }
Expand Down
1 change: 1 addition & 0 deletions all-is-cubes-desktop/src/bin/all-is-cubes/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ fn main() -> Result<(), anyhow::Error> {
let dsession = inner_params
.runtime
.block_on(create_winit_wgpu_desktop_session(
Arc::new(executor.clone()),
session,
// TODO: turn this inside out and stop having `WinAndState` exposed
aic_winit::WinAndState::new(
Expand Down
2 changes: 2 additions & 0 deletions all-is-cubes-desktop/src/winit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ pub fn winit_main_loop_and_init<Ren: RendererToWinit + 'static>(

/// Creates a [`DesktopSession`] that can be run in an [`winit`] event loop.
pub async fn create_winit_wgpu_desktop_session(
executor: Arc<crate::glue::Executor>,
session: Session,
window: WinAndState,
viewport_cell: ListenableCell<Viewport>,
Expand Down Expand Up @@ -258,6 +259,7 @@ pub async fn create_winit_wgpu_desktop_session(
session.create_cameras(viewport_cell.as_source()),
surface,
&adapter,
executor,
)
.await?;

Expand Down
1 change: 1 addition & 0 deletions all-is-cubes-gpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ rand = { workspace = true }
rand_xoshiro = { workspace = true }
rayon = { workspace = true, optional = true }
resource = "0.5.0"
send_wrapper = { workspace = true }
thiserror = { workspace = true }
wasm-bindgen-futures = { workspace = true }
# For initializing tests on web. (This is not a dev-dependency because some of said tests are not in this package.)
Expand Down
23 changes: 21 additions & 2 deletions all-is-cubes-gpu/src/in_wgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::marker::PhantomData;
use std::mem;
use std::sync::Arc;

use all_is_cubes::util::Executor;
use wgpu::TextureViewDescriptor;

use all_is_cubes::camera::{info_text_drawable, Layers, RenderMethod, StandardCameras};
Expand Down Expand Up @@ -102,6 +103,7 @@ impl<I: time::Instant> SurfaceRenderer<I> {
cameras: StandardCameras,
surface: wgpu::Surface<'static>,
adapter: &wgpu::Adapter,
executor: Arc<dyn Executor>,
) -> Result<Self, GraphicsResourceError> {
let (device, queue) = adapter
.request_device(
Expand All @@ -120,6 +122,7 @@ impl<I: time::Instant> SurfaceRenderer<I> {

let viewport_source = cameras.viewport_source();
let everything = EverythingRenderer::new(
executor,
device.clone(),
cameras,
choose_surface_format(&surface.get_capabilities(adapter)),
Expand Down Expand Up @@ -229,6 +232,8 @@ impl<I: time::Instant> SurfaceRenderer<I> {
/// scene and UI, but not the surface it's drawn on. This may be used in tests or
/// to support
struct EverythingRenderer<I: time::Instant> {
executor: Arc<dyn Executor>,

device: Arc<wgpu::Device>,

staging_belt: wgpu::util::StagingBelt,
Expand Down Expand Up @@ -275,6 +280,7 @@ impl<I: time::Instant> fmt::Debug for EverythingRenderer<I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// not at all clear how much is useful to print...
let Self {
executor,
device,
staging_belt,
cameras,
Expand All @@ -296,6 +302,7 @@ impl<I: time::Instant> fmt::Debug for EverythingRenderer<I> {
rerun_image: _,
} = self;
f.debug_struct("EverythingRenderer")
.field("executor", &executor)
.field("device", &device)
.field("staging_belt", &staging_belt)
.field("cameras", &cameras)
Expand All @@ -321,6 +328,7 @@ impl<I: time::Instant> EverythingRenderer<I> {
}

pub fn new(
executor: Arc<dyn Executor>,
device: Arc<wgpu::Device>,
cameras: StandardCameras,
surface_format: wgpu::TextureFormat,
Expand Down Expand Up @@ -424,6 +432,7 @@ impl<I: time::Instant> EverythingRenderer<I> {
#[cfg(feature = "rerun")]
rerun_image: rerun_image::RerunImageExport::new(device.clone()),

executor,
device,
config,
cameras,
Expand Down Expand Up @@ -517,11 +526,21 @@ impl<I: time::Instant> EverythingRenderer<I> {
// TODO: we should be able to express this as something like "Layers::zip()"
self.space_renderers
.world
.set_space(&self.device, &self.pipelines, spaces_to_render.world)
.set_space(
self.executor.clone(),
&self.device,
&self.pipelines,
spaces_to_render.world,
)
.map_err(GraphicsResourceError::read_err)?;
self.space_renderers
.ui
.set_space(&self.device, &self.pipelines, spaces_to_render.ui)
.set_space(
self.executor.clone(),
&self.device,
&self.pipelines,
spaces_to_render.ui,
)
.map_err(GraphicsResourceError::read_err)?;

let mut encoder = self
Expand Down
13 changes: 12 additions & 1 deletion all-is-cubes-gpu/src/in_wgpu/headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ use futures_core::future::BoxFuture;
use all_is_cubes::camera::{self, Flaws, HeadlessRenderer, StandardCameras, Viewport};
use all_is_cubes::character::Cursor;
use all_is_cubes::listen::{DirtyFlag, ListenableSource};
use all_is_cubes::util::Executor;

use crate::common::{AdaptedInstant, FrameBudget, GraphicsResourceError};
use crate::in_wgpu::{self, init};

/// Builder for the headless [`Renderer`].
#[derive(Clone, Debug)]
pub struct Builder {
executor: Arc<dyn Executor>,
adapter: Arc<wgpu::Adapter>,
device: Arc<wgpu::Device>,
queue: Arc<wgpu::Queue>,
adapter: Arc<wgpu::Adapter>,
}

impl Builder {
Expand All @@ -36,13 +38,22 @@ impl Builder {
device: Arc::new(device),
queue: Arc::new(queue),
adapter,
executor: Arc::new(()),
})
}

/// Set the executor for parallel calculations.
#[must_use]
pub fn executor(mut self, executor: Arc<dyn Executor>) -> Self {
self.executor = executor;
self
}

/// Create a [`Renderer`] from the GPU connection in this builder and the given cameras.
pub fn build(&self, cameras: StandardCameras) -> Renderer {
let viewport_source = cameras.viewport_source();
let everything = in_wgpu::EverythingRenderer::new(
self.executor.clone(),
self.device.clone(),
cameras,
wgpu::TextureFormat::Rgba8UnormSrgb,
Expand Down
23 changes: 23 additions & 0 deletions all-is-cubes-gpu/src/in_wgpu/space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use all_is_cubes::rerun_glue as rg;
use all_is_cubes::space::{Space, SpaceChange};
use all_is_cubes::time;
use all_is_cubes::universe::{RefError, URef};
use all_is_cubes::util::Executor;
use all_is_cubes_mesh::dynamic::{self, ChunkedSpaceMesh, RenderDataUpdate};
use all_is_cubes_mesh::{DepthOrdering, IndexSlice};

Expand Down Expand Up @@ -133,6 +134,7 @@ impl<I: time::Instant> SpaceRenderer<I> {
/// `set_space(..., None)` was called.
pub(crate) fn set_space(
&mut self,
executor: Arc<dyn Executor>,
device: &wgpu::Device,
_pipelines: &Pipelines,
space: Option<&URef<Space>>,
Expand Down Expand Up @@ -182,6 +184,27 @@ impl<I: time::Instant> SpaceRenderer<I> {
new_csm.log_to_rerun(self.rerun_destination.clone());
}

// Spawn background mesh jobs
executor.spawn_background(&mut || {
let task = {
let job_queue = new_csm.job_queue().clone();
let executor = executor.clone();
async move {
while let Some(job) = job_queue.next().await {
job.await;
executor.yield_now().await;
}
}
};

// On wasm, wgpu is not Send, but for the same reason, we never use any other threads,
// so a SendWrapper will make things work out.
#[cfg(target_family = "wasm")]
let task = send_wrapper::SendWrapper::new(task);

Box::pin(task)
});

*csm = Some(new_csm);

*sky_color = space_borrowed.physics().sky_color;
Expand Down
4 changes: 4 additions & 0 deletions all-is-cubes-wasm/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion all-is-cubes-wasm/src/init.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Startup; going from a JS function call to a running session.
use std::sync::Arc;

use js_sys::Error;
use rand::{thread_rng, Rng as _};
use send_wrapper::SendWrapper;
Expand Down Expand Up @@ -130,7 +132,13 @@ async fn start_game_with_dom(
})
.await
.ok_or("Could not request suitable graphics adapter")?;
let renderer = in_wgpu::SurfaceRenderer::new(cameras, surface, &adapter).await?;
let renderer = in_wgpu::SurfaceRenderer::new(
cameras,
surface,
&adapter,
Arc::new(crate::web_glue::Executor),
)
.await?;
WebRenderer::Wgpu(renderer)
}
};
Expand Down

0 comments on commit b6e2761

Please sign in to comment.