Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better error types #516

Merged
merged 18 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 39 additions & 38 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ raw-window-handle = { workspace = true }
static_assertions = { workspace = true }
futures-intrusive = { workspace = true }
wgpu-profiler = { workspace = true, optional = true }
thiserror = { workspace = true }

[workspace.lints]
clippy.doc_markdown = "warn"
Expand All @@ -80,6 +81,7 @@ futures-intrusive = "0.5.0"
raw-window-handle = "0.6.1"
smallvec = "1.13.2"
static_assertions = "1.1.0"
thiserror = "1.0.57"

# NOTE: Make sure to keep this in sync with the version badge in README.md
# as well as examples/simple/Cargo.toml
Expand Down
62 changes: 47 additions & 15 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub mod util;

pub use render::Render;
pub use scene::{DrawGlyphs, Scene};
use thiserror::Error;
#[cfg(feature = "wgpu")]
pub use util::block_on_wgpu;

Expand All @@ -126,12 +127,6 @@ use wgpu::{Device, PipelineCompilationOptions, Queue, SurfaceTexture, TextureFor
#[cfg(all(feature = "wgpu", feature = "wgpu-profiler"))]
use wgpu_profiler::{GpuProfiler, GpuProfilerSettings};

/// Catch-all error type.
pub type Error = Box<dyn std::error::Error>;

/// Specialization of `Result` for our catch-all error type.
pub type Result<T> = std::result::Result<T, Error>;

/// Represents the antialiasing method to use during a render pass.
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum AaConfig {
Expand Down Expand Up @@ -183,6 +178,47 @@ impl FromIterator<AaConfig> for AaSupport {
}
}

/// Errors that can occur in Vello.
#[derive(Error, Debug)]
#[non_exhaustive]
xStrom marked this conversation as resolved.
Show resolved Hide resolved
pub enum Error {
/// There is no available device with the features required by Vello.
#[cfg(feature = "wgpu")]
#[error("Couldn't find suitable device")]
NoCompatibleDevice,
/// Failed to create surface.
/// See [`wgpu::CreateSurfaceError`] for more information.
#[cfg(feature = "wgpu")]
#[error("Couldn't create wgpu surface")]
WgpuCreateSurfaceError(#[from] wgpu::CreateSurfaceError),
/// Surface doesn't support the required texture formats.
/// Make sure that you have a surface which provides one of
/// [`TextureFormat::Rgba8Unorm`] or [`TextureFormat::Bgra8Unorm`] as texture formats.
#[cfg(feature = "wgpu")]
#[error("Couldn't find `Rgba8Unorm` or `Bgra8Unorm` texture formats for surface")]
UnsupportedSurfaceFormat,

/// Used a buffer inside a recording while it was not available.
/// Check if you have created it and not freed before its last usage.
#[cfg(feature = "wgpu")]
#[error("Buffer '{0}' is not available but used for {1}")]
UnavailableBufferUsed(&'static str, &'static str),
/// Failed to async map a buffer.
/// See [`wgpu::BufferAsyncError`] for more information.
#[cfg(feature = "wgpu")]
#[error("Failed to async map a buffer")]
BufferAsyncError(#[from] wgpu::BufferAsyncError),

/// Failed to create [`GpuProfiler`].
/// See [`wgpu_profiler::CreationError`] for more information.
#[cfg(feature = "wgpu-profiler")]
#[error("Couldn't create wgpu profiler")]
ProfilerCreationError(#[from] wgpu_profiler::CreationError),
}

#[allow(dead_code)] // this can be unused when wgpu feature is not used
pub(crate) type Result<T, E = Error> = std::result::Result<T, E>;

/// Renders a scene into a texture or surface.
#[cfg(feature = "wgpu")]
pub struct Renderer {
Expand Down Expand Up @@ -257,7 +293,7 @@ impl Renderer {
#[cfg(not(target_arch = "wasm32"))]
engine.use_parallel_initialisation();
}
let shaders = shaders::full_shaders(device, &mut engine, &options)?;
let shaders = shaders::full_shaders(device, &mut engine, &options);
#[cfg(not(target_arch = "wasm32"))]
engine.build_shaders_if_needed(device, options.num_init_threads);
let blit = options
Expand Down Expand Up @@ -399,14 +435,14 @@ impl Renderer {

/// Reload the shaders. This should only be used during `vello` development
#[cfg(feature = "hot_reload")]
pub async fn reload_shaders(&mut self, device: &Device) -> Result<()> {
pub async fn reload_shaders(&mut self, device: &Device) -> Result<(), wgpu::Error> {
device.push_error_scope(wgpu::ErrorFilter::Validation);
let mut engine = WgpuEngine::new(self.options.use_cpu);
// We choose not to initialise these shaders in parallel, to ensure the error scope works correctly
let shaders = shaders::full_shaders(device, &mut engine, &self.options)?;
let shaders = shaders::full_shaders(device, &mut engine, &self.options);
let error = device.pop_error_scope().await;
if let Some(error) = error {
return Err(error.into());
return Err(error);
}
self.engine = engine;
self.shaders = shaders;
Expand Down Expand Up @@ -460,11 +496,7 @@ impl Renderer {
let buf_slice = bump_buf.slice(..);
let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel();
buf_slice.map_async(wgpu::MapMode::Read, move |v| sender.send(v).unwrap());
if let Some(recv_result) = receiver.receive().await {
recv_result?;
} else {
return Err("channel was closed".into());
}
receiver.receive().await.expect("channel was closed")?;
simbleau marked this conversation as resolved.
Show resolved Hide resolved
let mapped = buf_slice.get_mapped_range();
bump = Some(bytemuck::pod_read_unaligned(&mapped));
}
Expand Down
Loading