22
33use std:: borrow:: Cow ;
44use std:: cell:: RefCell ;
5+ use std:: sync:: atomic:: { AtomicBool , Ordering } ;
56
67use deno_core:: cppgc:: Ptr ;
78use deno_core:: op2;
@@ -28,11 +29,19 @@ pub struct GPUCommandEncoder {
2829
2930 pub id : wgpu_core:: id:: CommandEncoderId ,
3031 pub label : String ,
32+
33+ pub finished : AtomicBool ,
3134}
3235
3336impl Drop for GPUCommandEncoder {
3437 fn drop ( & mut self ) {
35- self . instance . command_encoder_drop ( self . id ) ;
38+ // Command encoders and command buffers are both the same wgpu object.
39+ // At the time `finished` is set, ownership of the id (and
40+ // responsibility for dropping it) transfers from the encoder to the
41+ // buffer.
42+ if !self . finished . load ( Ordering :: SeqCst ) {
43+ self . instance . command_encoder_drop ( self . id ) ;
44+ }
3645 }
3746}
3847
@@ -407,23 +416,34 @@ impl GPUCommandEncoder {
407416 fn finish (
408417 & self ,
409418 #[ webidl] descriptor : crate :: command_buffer:: GPUCommandBufferDescriptor ,
410- ) -> GPUCommandBuffer {
419+ ) -> Result < GPUCommandBuffer , JsErrorBox > {
411420 let wgpu_descriptor = wgpu_types:: CommandBufferDescriptor {
412421 label : crate :: transform_label ( descriptor. label . clone ( ) ) ,
413422 } ;
414423
424+ // TODO(https://github.com/gfx-rs/wgpu/issues/7812): This is not right,
425+ // it should be a validation error, and it would be nice if we can just
426+ // let wgpu generate it for us. The problem is that if the encoder was
427+ // already finished, we transferred ownership of the id to a command
428+ // buffer, so we have to bail out before we mint a duplicate command
429+ // buffer with the same id below.
430+ if self . finished . fetch_or ( true , Ordering :: SeqCst ) {
431+ return Err ( JsErrorBox :: type_error (
432+ "The command encoder has already finished." ,
433+ ) ) ;
434+ }
435+
415436 let ( id, err) = self
416437 . instance
417438 . command_encoder_finish ( self . id , & wgpu_descriptor) ;
418439
419440 self . error_handler . push_error ( err) ;
420441
421- GPUCommandBuffer {
442+ Ok ( GPUCommandBuffer {
422443 instance : self . instance . clone ( ) ,
423444 id,
424445 label : descriptor. label ,
425- consumed : Default :: default ( ) ,
426- }
446+ } )
427447 }
428448
429449 fn push_debug_group ( & self , #[ webidl] group_label : String ) {
0 commit comments