pub(crate) struct PendingWrites {
pub command_encoder: Box<dyn DynCommandEncoder>,
pub is_recording: bool,
temp_resources: Vec<TempResource>,
dst_buffers: FastHashMap<TrackerIndex, Arc<Buffer>>,
dst_textures: FastHashMap<TrackerIndex, Arc<Texture>>,
copied_blas_s: FastHashMap<TrackerIndex, Arc<Blas>>,
instance_flags: InstanceFlags,
hoisted_staging_buffers: Vec<FlushedStagingBuffer>,
hoisted_buffer_barriers: Vec<(Arc<Buffer>, StateTransition<BufferUses>)>,
}Expand description
A private command encoder for writes made directly on the device or queue.
Operations like buffer_unmap, queue_write_buffer, and
queue_write_texture need to copy data to the GPU. At the hal
level, this must be done by encoding and submitting commands, but
these operations are not associated with any specific wgpu command
buffer.
Instead, Device::pending_writes owns one of these values, which
has its own hal command encoder and resource lists. The commands
accumulated here are automatically submitted to the queue at the
sooner of:
- The user’s next wgpu command buffer submission. (Pending writes are inserted ahead of the user’s commands.)
- The next
mapAsyncrequest for a buffer that has pending writes.
Important: When locking pending_writes be sure that tracker is not locked and try to lock trackers for the minimum timespan possible
All uses of StagingBuffers end up here.
Fields§
§command_encoder: Box<dyn DynCommandEncoder>§is_recording: boolTrue if command_encoder is in the “recording” state, as
described in the docs for the wgpu_hal::CommandEncoder
trait.
temp_resources: Vec<TempResource>§dst_buffers: FastHashMap<TrackerIndex, Arc<Buffer>>§dst_textures: FastHashMap<TrackerIndex, Arc<Texture>>§copied_blas_s: FastHashMap<TrackerIndex, Arc<Blas>>§instance_flags: InstanceFlags§hoisted_staging_buffers: Vec<FlushedStagingBuffer>Staging buffers that are the source of a copy recorded in
command_encoder, and so need a MAP_WRITE -> COPY_SRC transition.
See hoisted_buffer_barriers for why these are not recorded
immediately. Moved to temp_resources in pre_submit.
hoisted_buffer_barriers: Vec<(Arc<Buffer>, StateTransition<BufferUses>)>Buffer transitions that must happen before the copies recorded in
command_encoder.
Recording a barrier immediately before each copy means that a frame
which calls Queue::write_buffer a few dozen times ends up with many
back-to-back barrier/copy pairs, when a single barrier covering every
buffer would have done just as well.
Instead we accumulate the transitions here and record them all at once,
into a command buffer that pre_submit places in front of
command_encoder’s.
Only a buffer’s first transition in a batch may be hoisted like this.
A buffer written more than once per batch gets a second, COPY_DST ->
COPY_DST transition from the tracker (unless the adapter reports
COPY_DST as an ordered usage), and that barrier exists precisely to
separate the two copies, so it has to stay where it was recorded. See
hoist_buffer_barrier.
Implementations§
Source§impl PendingWrites
impl PendingWrites
pub fn new( command_encoder: Box<dyn DynCommandEncoder>, instance_flags: InstanceFlags, ) -> Self
pub fn insert_buffer(&mut self, buffer: &Arc<Buffer>)
pub fn insert_texture(&mut self, texture: &Arc<Texture>)
pub fn insert_blas(&mut self, blas: &Arc<Blas>)
pub fn contains_buffer(&self, buffer: &Arc<Buffer>) -> bool
pub fn contains_texture(&self, texture: &Arc<Texture>) -> bool
pub fn consume_temp(&mut self, resource: TempResource)
Sourcepub fn consume(&mut self, buffer: FlushedStagingBuffer)
pub fn consume(&mut self, buffer: FlushedStagingBuffer)
Take ownership of a staging buffer that is the source of a copy recorded into this batch.
This also queues up the staging buffer’s MAP_WRITE -> COPY_SRC
transition, so callers must not record one themselves.
Sourcefn hoist_buffer_barrier(
&mut self,
buffer: &Arc<Buffer>,
transition: Option<PendingTransition<BufferUses>>,
) -> Option<PendingTransition<BufferUses>>
fn hoist_buffer_barrier( &mut self, buffer: &Arc<Buffer>, transition: Option<PendingTransition<BufferUses>>, ) -> Option<PendingTransition<BufferUses>>
Queue up a buffer transition to be recorded ahead of this batch’s copies.
Returns the transition instead if it cannot be hoisted, in which case
the caller must record it immediately, before its own copy. This happens
when this batch has already copied into buffer: the transition is then
a COPY_DST -> COPY_DST write-after-write barrier separating the
earlier copy from the caller’s, as hoisting it to the front of the
batch would leave the two copies unsynchronized.
pub fn clear_buffer( &mut self, device: &Arc<Device>, buffer: &Arc<Buffer>, range: Range<BufferAddress>, snatch_guard: &SnatchGuard<'_>, ) -> Result<(), QueueWriteError>
Sourcefn record_hoisted_barriers(
&mut self,
encoder: &mut EncoderInFlight,
snatch_guard: &SnatchGuard<'_>,
) -> Result<Vec<FlushedStagingBuffer>, DeviceError>
fn record_hoisted_barriers( &mut self, encoder: &mut EncoderInFlight, snatch_guard: &SnatchGuard<'_>, ) -> Result<Vec<FlushedStagingBuffer>, DeviceError>
Record every transition this batch of writes needs as a single barrier, into a command buffer placed ahead of the one holding the batch’s copies.
Returns the staging buffers whose transitions were recorded. The caller is responsible for keeping them alive until the submission completes.
fn pre_submit( &mut self, command_allocator: &CommandAllocator, device: &Arc<Device>, queue: &Queue, snatch_guard: &SnatchGuard<'_>, ) -> Result<Option<EncoderInFlight>, DeviceError>
pub fn activate(&mut self) -> &mut dyn DynCommandEncoder
Trait Implementations§
Source§impl Debug for PendingWrites
impl Debug for PendingWrites
Auto Trait Implementations§
impl Freeze for PendingWrites
impl !RefUnwindSafe for PendingWrites
impl Send for PendingWrites
impl Sync for PendingWrites
impl Unpin for PendingWrites
impl UnsafeUnpin for PendingWrites
impl !UnwindSafe for PendingWrites
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more