@@ -897,27 +897,53 @@ impl<C: Clone, E: Clone> BasePass<C, E> {
897
897
}
898
898
}
899
899
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.
900
922
macro_rules! pass_base {
901
923
( $pass: expr, $scope: expr $( , ) ?) => {
902
924
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
905
926
( & 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
912
928
( & Some ( _) , & Some ( _) ) => return Ok ( ( ) ) ,
913
-
914
- // Happy path
929
+ // Pass is open and valid
915
930
( & Some ( _) , & None ) => & mut $pass. base,
916
931
}
917
932
} ;
918
933
}
919
934
pub ( crate ) use pass_base;
920
935
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.
921
947
macro_rules! pass_try {
922
948
( $base: expr, $scope: expr, $res: expr $( , ) ?) => {
923
949
match $res. map_pass_err( $scope) {
@@ -1302,6 +1328,7 @@ impl Default for BindGroupStateChange {
1302
1328
}
1303
1329
}
1304
1330
1331
+ /// Helper to attach [`PassErrorScope`] to errors.
1305
1332
trait MapPassErr < T > {
1306
1333
fn map_pass_err ( self , scope : PassErrorScope ) -> T ;
1307
1334
}
@@ -1329,6 +1356,15 @@ pub enum DrawKind {
1329
1356
MultiDrawIndirectCount ,
1330
1357
}
1331
1358
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.
1332
1368
#[ derive( Clone , Copy , Debug , Error ) ]
1333
1369
pub enum PassErrorScope {
1334
1370
// TODO: Extract out the 2 error variants below so that we can always
0 commit comments