@@ -49,6 +49,8 @@ pub enum CpuWriteGpuReadError {
49
49
/// Note that the "vec like behavior" further encourages
50
50
/// * not leaving holes
51
51
/// * keeping writes sequential
52
+ ///
53
+ /// Must be dropped before calling [`CpuWriteGpuReadBelt::before_queue_submit`] (typically the end of a frame).
52
54
pub struct CpuWriteGpuReadBuffer < T : bytemuck:: Pod + Send + Sync > {
53
55
/// Write view into the relevant buffer portion.
54
56
write_view : wgpu:: BufferViewMut ,
@@ -551,7 +553,10 @@ impl CpuWriteGpuReadBelt {
551
553
552
554
/// Prepare currently mapped buffers for use in a submission.
553
555
///
554
- /// This must be called before the command encoder(s) used in [`CpuWriteGpuReadBuffer`] copy operations are submitted.
556
+ /// All existing [`CpuWriteGpuReadBuffer`] MUST be dropped before calling this function.
557
+ /// Any not dropped [`CpuWriteGpuReadBuffer`] will cause a validation error.
558
+ ///
559
+ /// This must be called BEFORE the command encoder(s) used in any [`CpuWriteGpuReadBuffer`] copy operations are submitted.
555
560
///
556
561
/// At this point, all the partially used staging buffers are closed (cannot be used for
557
562
/// further writes) until after [`CpuWriteGpuReadBelt::after_queue_submit`] is called *and* the GPU is done
@@ -563,6 +568,10 @@ impl CpuWriteGpuReadBelt {
563
568
// https://github.com/gfx-rs/wgpu/issues/1468
564
569
// However, WebGPU does not support this!
565
570
571
+ // We're done with writing to this chunk and are ready to have the GPU read it!
572
+ //
573
+ // This part has to happen before submit, otherwise we get a validation error that
574
+ // the buffers are still mapped and can't be read by the gpu.
566
575
for chunk in self . active_chunks . drain ( ..) {
567
576
chunk. buffer . unmap ( ) ;
568
577
self . closed_chunks . push ( chunk) ;
@@ -574,12 +583,16 @@ impl CpuWriteGpuReadBelt {
574
583
/// This must only be called after the command encoder(s) used in [`CpuWriteGpuReadBuffer`]
575
584
/// copy operations are submitted. Additional calls are harmless.
576
585
/// Not calling this as soon as possible may result in increased buffer memory usage.
586
+ ///
587
+ /// Implementation note:
588
+ /// We can't use [`wgpu::CommandEncoder::map_buffer_on_submit`] here because for that we'd need to know which
589
+ /// command encoder is the last one scheduling any cpu->gpu copy operations.
590
+ /// Note that if chunks were fully tied to a single encoder, we could call [`wgpu::CommandEncoder::map_buffer_on_submit`]
591
+ /// once we know a chunk has all its cpu->gpu copy operations scheduled on that very encoder.
577
592
pub fn after_queue_submit ( & mut self ) {
578
593
re_tracing:: profile_function!( ) ;
579
594
self . receive_chunks ( ) ;
580
595
581
- // TODO(andreas): Use `map_buffer_on_submit` https://github.com/gfx-rs/wgpu/pull/8125 once available.
582
-
583
596
let sender = & self . sender ;
584
597
for chunk in self . closed_chunks . drain ( ..) {
585
598
let sender = sender. clone ( ) ;
0 commit comments