@@ -86,6 +86,8 @@ pub(crate) enum CommandEncoderStatus {
86
86
/// <https://www.w3.org/TR/webgpu/#encoder-state-locked>
87
87
Locked ( CommandBufferMutable ) ,
88
88
89
+ Consumed ,
90
+
89
91
/// Command recording is complete, and the buffer is ready for submission.
90
92
///
91
93
/// [`Global::command_encoder_finish`] transitions a
@@ -145,9 +147,7 @@ impl CommandEncoderStatus {
145
147
// Encoder is ended. Invalidate the encoder, do not record anything,
146
148
// and return an immediate validation error.
147
149
Self :: Finished ( _) => Err ( self . invalidate ( EncoderStateError :: Ended ) ) ,
148
- Self :: Error ( CommandEncoderError :: State ( EncoderStateError :: Ended ) ) => {
149
- Err ( EncoderStateError :: Ended )
150
- }
150
+ Self :: Consumed => Err ( EncoderStateError :: Ended ) ,
151
151
// Encoder is already invalid. Do not record anything, but do not
152
152
// return an immediate validation error.
153
153
Self :: Error ( _) => Ok ( ( ) ) ,
@@ -176,7 +176,7 @@ impl CommandEncoderStatus {
176
176
self . invalidate ( EncoderStateError :: Ended ) ;
177
177
f ( None )
178
178
}
179
- Self :: Error ( CommandEncoderError :: State ( EncoderStateError :: Ended ) ) => f ( None ) ,
179
+ Self :: Consumed => f ( None ) ,
180
180
Self :: Error ( _) => f ( None ) ,
181
181
Self :: Transitioning => unreachable ! ( ) ,
182
182
}
@@ -190,6 +190,7 @@ impl CommandEncoderStatus {
190
190
// playing back a recorded trace. If only to avoid having to
191
191
// implement serialization for all the error types, we don't support
192
192
// storing the errors in a trace.
193
+ Self :: Consumed => unreachable ! ( "command encoder is consumed" ) ,
193
194
Self :: Error ( _) => unreachable ! ( "passes in a trace do not store errors" ) ,
194
195
Self :: Transitioning => unreachable ! ( ) ,
195
196
}
@@ -214,7 +215,7 @@ impl CommandEncoderStatus {
214
215
Err ( EncoderStateError :: Ended )
215
216
}
216
217
Self :: Locked ( _) => Err ( self . invalidate ( EncoderStateError :: Locked ) ) ,
217
- st @ Self :: Error ( CommandEncoderError :: State ( EncoderStateError :: Ended ) ) => {
218
+ st @ Self :: Consumed => {
218
219
* self = st;
219
220
Err ( EncoderStateError :: Ended )
220
221
}
@@ -262,7 +263,7 @@ impl CommandEncoderStatus {
262
263
* self = Self :: Error ( EncoderStateError :: Unlocked . into ( ) ) ;
263
264
Err ( EncoderStateError :: Unlocked )
264
265
}
265
- st @ Self :: Error ( CommandEncoderError :: State ( EncoderStateError :: Ended ) ) => {
266
+ st @ Self :: Consumed => {
266
267
* self = st;
267
268
Err ( EncoderStateError :: Ended )
268
269
}
@@ -276,21 +277,22 @@ impl CommandEncoderStatus {
276
277
}
277
278
}
278
279
279
- fn finish ( & mut self ) -> Result < ( ) , CommandEncoderError > {
280
- match mem:: replace ( self , Self :: Transitioning ) {
280
+ fn finish ( & mut self ) -> Self {
281
+ // Replace our state with `Consumed`, and return either the inner
282
+ // state or an error, to be transferred to the command buffer.
283
+ match mem:: replace ( self , Self :: Consumed ) {
281
284
Self :: Recording ( mut inner) => {
282
- if let Err ( e ) = inner. encoder . close_if_open ( ) {
283
- Err ( self . invalidate ( e . into ( ) ) )
285
+ if let Err ( err ) = inner. encoder . close_if_open ( ) {
286
+ Self :: Error ( err . into ( ) )
284
287
} else {
285
- * self = Self :: Finished ( inner) ;
286
288
// Note: if we want to stop tracking the swapchain texture view,
287
289
// this is the place to do it.
288
- Ok ( ( ) )
290
+ Self :: Finished ( inner )
289
291
}
290
292
}
291
- Self :: Finished ( _) => Err ( self . invalidate ( EncoderStateError :: Ended . into ( ) ) ) ,
292
- Self :: Locked ( _) => Err ( self . invalidate ( EncoderStateError :: Locked . into ( ) ) ) ,
293
- Self :: Error ( err ) => Err ( self . invalidate ( err ) ) ,
293
+ Self :: Consumed | Self :: Finished ( _) => Self :: Error ( EncoderStateError :: Ended . into ( ) ) ,
294
+ Self :: Locked ( _) => Self :: Error ( EncoderStateError :: Locked . into ( ) ) ,
295
+ st @ Self :: Error ( _ ) => st ,
294
296
Self :: Transitioning => unreachable ! ( ) ,
295
297
}
296
298
}
@@ -828,10 +830,7 @@ impl CommandBuffer {
828
830
) {
829
831
St :: Finished ( command_buffer_mutable) => Ok ( command_buffer_mutable) ,
830
832
St :: Error ( err) => Err ( err) ,
831
- St :: Recording ( _) | St :: Locked ( _) => {
832
- Err ( InvalidResourceError ( self . error_ident ( ) ) . into ( ) )
833
- }
834
- St :: Transitioning => unreachable ! ( ) ,
833
+ St :: Recording ( _) | St :: Locked ( _) | St :: Consumed | St :: Transitioning => unreachable ! ( ) ,
835
834
}
836
835
}
837
836
}
@@ -1143,22 +1142,15 @@ impl Global {
1143
1142
1144
1143
let cmd_enc = hub. command_encoders . get ( encoder_id) ;
1145
1144
1146
- let mut data_guard = cmd_enc. data . lock ( ) ;
1145
+ let data = cmd_enc. data . lock ( ) . finish ( ) ;
1147
1146
1148
1147
// Errors related to destroyed resources are not reported until the
1149
1148
// command buffer is submitted.
1150
- let error = match data_guard . finish ( ) {
1151
- Err ( e) if !e. is_destroyed_error ( ) => Some ( e) ,
1149
+ let error = match data {
1150
+ CommandEncoderStatus :: Error ( ref e) if !e. is_destroyed_error ( ) => Some ( e. clone ( ) ) ,
1152
1151
_ => None ,
1153
1152
} ;
1154
1153
1155
- let data = mem:: replace (
1156
- & mut * data_guard,
1157
- CommandEncoderStatus :: Error ( EncoderStateError :: Ended . into ( ) ) ,
1158
- ) ;
1159
-
1160
- drop ( data_guard) ;
1161
-
1162
1154
let cmd_buf = CommandBuffer {
1163
1155
device : cmd_enc. device . clone ( ) ,
1164
1156
label : desc. label . to_string ( ) ,
0 commit comments