Skip to content

Commit e936c06

Browse files
committed
Additional comments on render and compute pass encoding
1 parent 7722c34 commit e936c06

File tree

3 files changed

+69
-10
lines changed

3 files changed

+69
-10
lines changed

wgpu-core/src/command/compute.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,17 @@ fn write_timestamp(
11621162
}
11631163

11641164
// Recording a compute pass.
1165+
//
1166+
// The only error that should be returned from these methods is
1167+
// `EncoderStateError::Ended`, when the pass has already ended and an immediate
1168+
// validation error is raised.
1169+
//
1170+
// All other errors should be stored in the pass for later reporting when
1171+
// `CommandEncoder.finish()` is called.
1172+
//
1173+
// The `pass_try!` macro should be used to handle errors appropriately. Note
1174+
// that the `pass_try!` and `pass_base!` macros may return early from the
1175+
// function that invokes them, like the `?` operator.
11651176
impl Global {
11661177
pub fn compute_pass_set_bind_group(
11671178
&self,

wgpu-core/src/command/mod.rs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -897,27 +897,53 @@ impl<C: Clone, E: Clone> BasePass<C, E> {
897897
}
898898
}
899899

900+
/// Checks the state of a [`compute::ComputePass`] or [`render::RenderPass`] and
901+
/// evaluates to a mutable reference to the [`BasePass`], if the pass is open and
902+
/// valid.
903+
///
904+
/// If the pass is ended or not valid, **returns from the invoking function**,
905+
/// like the `?` operator.
906+
///
907+
/// If the pass is ended (i.e. the application is attempting to record a command
908+
/// on a finished pass), returns `Err(EncoderStateError::Ended)` from the
909+
/// invoking function, for immediate propagation as a validation error.
910+
///
911+
/// If the pass is open but invalid (i.e. a previous command encountered an
912+
/// error), returns `Ok(())` from the invoking function. The pass should already
913+
/// have stored the previous error, which will be transferred to the parent
914+
/// encoder when the pass is ended, and then raised as a validation error when
915+
/// `finish()` is called for the parent).
916+
///
917+
/// Although in many cases the functionality of `pass_base!` could be achieved
918+
/// by combining a helper method on the passes with the `pass_try!` macro,
919+
/// taking the mutable reference to the base pass in a macro avoids borrowing
920+
/// conflicts when a reference to some other member of the pass struct is
921+
/// needed simultaneously with the base pass reference.
900922
macro_rules! pass_base {
901923
($pass:expr, $scope:expr $(,)?) => {
902924
match (&$pass.parent, &$pass.base.error) {
903-
// Attempting to record a command on a finished encoder raises a
904-
// validation error.
925+
// Pass is ended
905926
(&None, _) => return Err(EncoderStateError::Ended).map_pass_err($scope),
906-
907-
// Attempting to record a command on an open but invalid pass (i.e.
908-
// a pass with a stored error) fails silently. (The stored error
909-
// will be transferred to the parent encoder when the pass is ended,
910-
// and then raised as a validation error when `finish()` is called
911-
// for the parent).
927+
// Pass is invalid
912928
(&Some(_), &Some(_)) => return Ok(()),
913-
914-
// Happy path
929+
// Pass is open and valid
915930
(&Some(_), &None) => &mut $pass.base,
916931
}
917932
};
918933
}
919934
pub(crate) use pass_base;
920935

936+
/// Handles the error case in an expression of type `Result<T, E>`.
937+
///
938+
/// This macro operates like the `?` operator (or, in early Rust versions, the
939+
/// `try!` macro, hence the name `pass_try`). **When there is an error, the
940+
/// macro returns from the invoking function.** However, `Ok(())`, and not the
941+
/// error itself, is returned. The error is stored in the pass and will later be
942+
/// transferred to the parent encoder when the pass ends, and then raised as a
943+
/// validation error when `finish()` is called for the parent.
944+
///
945+
/// `pass_try!` also calls [`MapPassErr::map_pass_err`] to annotate the error
946+
/// with the command being encoded at the time it occurred.
921947
macro_rules! pass_try {
922948
($base:expr, $scope:expr, $res:expr $(,)?) => {
923949
match $res.map_pass_err($scope) {
@@ -1302,6 +1328,7 @@ impl Default for BindGroupStateChange {
13021328
}
13031329
}
13041330

1331+
/// Helper to attach [`PassErrorScope`] to errors.
13051332
trait MapPassErr<T> {
13061333
fn map_pass_err(self, scope: PassErrorScope) -> T;
13071334
}
@@ -1329,6 +1356,15 @@ pub enum DrawKind {
13291356
MultiDrawIndirectCount,
13301357
}
13311358

1359+
/// A command that can be recorded in a pass or bundle.
1360+
///
1361+
/// This is used to provide context for errors during command recording.
1362+
/// [`MapPassErr`] is used as a helper to attach a `PassErrorScope` to
1363+
/// an error.
1364+
///
1365+
/// The [`PassErrorScope::Bundle`] and [`PassErrorScope::Pass`] variants
1366+
/// are used when the error occurs during the opening or closing of the
1367+
/// pass or bundle.
13321368
#[derive(Clone, Copy, Debug, Error)]
13331369
pub enum PassErrorScope {
13341370
// TODO: Extract out the 2 error variants below so that we can always

wgpu-core/src/command/render.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3119,6 +3119,18 @@ fn execute_bundle(
31193119
Ok(())
31203120
}
31213121

3122+
// Recording a render pass.
3123+
//
3124+
// The only error that should be returned from these methods is
3125+
// `EncoderStateError::Ended`, when the pass has already ended and an immediate
3126+
// validation error is raised.
3127+
//
3128+
// All other errors should be stored in the pass for later reporting when
3129+
// `CommandEncoder.finish()` is called.
3130+
//
3131+
// The `pass_try!` macro should be used to handle errors appropriately. Note
3132+
// that the `pass_try!` and `pass_base!` macros may return early from the
3133+
// function that invokes them, like the `?` operator.
31223134
impl Global {
31233135
fn resolve_render_pass_buffer_id(
31243136
&self,

0 commit comments

Comments
 (0)