Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
4 changes: 2 additions & 2 deletions _release-content/release-notes/render-recovery.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Render Recovery"
authors: ["@atlv24"]
pull_requests: [22761, 23350, 23349, 23433, 23458, 23444, 23459, 23461, 23463, 22714, 22759, 16481]
pull_requests: [22761, 23350, 23349, 23433, 23458, 23444, 23459, 23461, 23463, 22714, 22759, 16481, 24131]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm working on revising the release notes right now, and have pre-emptively included this PR. Please just accept those changes when resolving conflicts.

---

You can now recover from rendering errors such as device loss by reloading the renderer:
Expand All @@ -21,4 +21,4 @@ app.insert_resource(RenderErrorHandler(

NOTE: this is just an example showing the different errors and policies available, and not a recommendation for how to handle errors.

The default error handler behaves identically to how Bevy behaved before: validation errors are ignored, and other errors crash/hang the application.
The default error handler will quit the application on any RenderError.
Comment thread
kfc35 marked this conversation as resolved.
Outdated
29 changes: 22 additions & 7 deletions crates/bevy_render/src/error_handler.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use alloc::sync::Arc;
use bevy_app::AppExit;
use bevy_ecs::{
resource::Resource,
world::{Mut, World},
Expand All @@ -19,6 +20,11 @@ use crate::{
pub enum RenderErrorPolicy {
/// Pretends nothing happened and continues rendering.
/// This discards the error after logging it to console.
Comment thread
kfc35 marked this conversation as resolved.
/// WARNING: Using this policy could cause hazardous rapid flashing
/// if the conditions causing the error remain unaddressed, since
/// rendering will attempt to continue executing.
/// When choosing to use this policy, be sure to test that the application
/// remains safe to use.
Ignore,
/// Keeps the app alive, but stops rendering further.
/// This keeps the error state, and will continue polling the [`RenderErrorHandler`]
Expand All @@ -32,9 +38,11 @@ pub enum RenderErrorPolicy {
///
/// The handler has access to both the main world and the render world in that order.
/// By the time this is invoked, the error has already been logged. The error is provided
/// for the decision-making reason of how to appropriately respond to it. Not all errors
/// are equally severe: validation errors may be ignored for example, while device lost errors
/// require recovery to continue rendering.
/// for the decision-making reason of how to appropriately respond to it.
///
/// Note that failing to address the source of an error and continuing to render may cause rapid flashing.
/// Be sure to thoroughly test your error handler to ensure you application remains safe
/// to use.
#[derive(Resource)]
pub struct RenderErrorHandler(
pub for<'a> fn(&'a RenderError, &'a mut World, &'a mut World) -> RenderErrorPolicy,
Expand All @@ -60,13 +68,20 @@ impl RenderErrorHandler {

impl Default for RenderErrorHandler {
fn default() -> Self {
// This is what we've always done historically,
// but we could choose a new default once recovery works better.
Self(|_, _, _| RenderErrorPolicy::Ignore)
// Quit the application for any `RenderError`.
// These `RenderError`s originate from wgpu. Ignoring a wgpu OutOfMemory
// or wgpu Validation error without addressing the root cause can
// create a rendering loop that delivers hazardous strobing effects.
// We can choose a new default once recovery works better.
Comment thread
kfc35 marked this conversation as resolved.
Outdated
Self(|error, main_world, _| {
bevy_log::error!("Quitting the application due to {:?} RenderError", error.ty);
main_world.write_message(AppExit::error());
RenderErrorPolicy::StopRendering
})
}
}

/// An error encountered during rendering.
/// An error encountered during rendering. These errors come from wgpu.
Comment thread
kfc35 marked this conversation as resolved.
Outdated
#[derive(Debug)]
pub struct RenderError {
pub ty: ErrorType,
Expand Down
Loading