remove PendingWrites.executing_command_buffers

The Vec only ever contained 0 or 1 command buffers.
We now acquire an encoder on every submit for pending writes but that's not a problem since those are coming from a pool anyway.
This commit is contained in:
teoxoy 2024-07-04 16:45:14 +02:00 committed by Teodor Tanasoaia
parent 439e28bfc1
commit 61739d9583

View File

@ -60,13 +60,6 @@ impl<A: HalApi> Drop for Queue<A> {
} }
} }
/// Number of command buffers that we generate from the same pool
/// for the write_xxx commands, before the pool is recycled.
///
/// If we don't stop at some point, the pool will grow forever,
/// without a concrete moment of when it can be cleared.
const WRITE_COMMAND_BUFFERS_PER_POOL: usize = 64;
#[repr(C)] #[repr(C)]
pub struct SubmittedWorkDoneClosureC { pub struct SubmittedWorkDoneClosureC {
pub callback: unsafe extern "C" fn(user_data: *mut u8), pub callback: unsafe extern "C" fn(user_data: *mut u8),
@ -209,9 +202,6 @@ pub(crate) struct PendingWrites<A: HalApi> {
temp_resources: Vec<TempResource<A>>, temp_resources: Vec<TempResource<A>>,
dst_buffers: FastHashMap<TrackerIndex, Arc<Buffer<A>>>, dst_buffers: FastHashMap<TrackerIndex, Arc<Buffer<A>>>,
dst_textures: FastHashMap<TrackerIndex, Arc<Texture<A>>>, dst_textures: FastHashMap<TrackerIndex, Arc<Texture<A>>>,
/// All command buffers allocated from `command_encoder`.
pub executing_command_buffers: Vec<A::CommandBuffer>,
} }
impl<A: HalApi> PendingWrites<A> { impl<A: HalApi> PendingWrites<A> {
@ -222,7 +212,6 @@ impl<A: HalApi> PendingWrites<A> {
temp_resources: Vec::new(), temp_resources: Vec::new(),
dst_buffers: FastHashMap::default(), dst_buffers: FastHashMap::default(),
dst_textures: FastHashMap::default(), dst_textures: FastHashMap::default(),
executing_command_buffers: Vec::new(),
} }
} }
@ -231,8 +220,6 @@ impl<A: HalApi> PendingWrites<A> {
if self.is_recording { if self.is_recording {
self.command_encoder.discard_encoding(); self.command_encoder.discard_encoding();
} }
self.command_encoder
.reset_all(self.executing_command_buffers.into_iter());
device.destroy_command_encoder(self.command_encoder); device.destroy_command_encoder(self.command_encoder);
} }
@ -266,36 +253,27 @@ impl<A: HalApi> PendingWrites<A> {
.push(TempResource::StagingBuffer(buffer)); .push(TempResource::StagingBuffer(buffer));
} }
fn pre_submit(&mut self) -> Result<Option<&A::CommandBuffer>, DeviceError> { fn pre_submit(
&mut self,
command_allocator: &CommandAllocator<A>,
device: &A::Device,
queue: &A::Queue,
) -> Result<Option<EncoderInFlight<A>>, DeviceError> {
self.dst_buffers.clear(); self.dst_buffers.clear();
self.dst_textures.clear(); self.dst_textures.clear();
if self.is_recording { if self.is_recording {
let cmd_buf = unsafe { self.command_encoder.end_encoding()? }; let cmd_buf = unsafe { self.command_encoder.end_encoding()? };
self.is_recording = false; self.is_recording = false;
self.executing_command_buffers.push(cmd_buf);
return Ok(self.executing_command_buffers.last()); let new_encoder = command_allocator.acquire_encoder(device, queue)?;
}
Ok(None) Ok(Some(EncoderInFlight {
}
#[must_use]
fn post_submit(
&mut self,
command_allocator: &CommandAllocator<A>,
device: &A::Device,
queue: &A::Queue,
) -> Option<EncoderInFlight<A>> {
if self.executing_command_buffers.len() >= WRITE_COMMAND_BUFFERS_PER_POOL {
let new_encoder = command_allocator.acquire_encoder(device, queue).unwrap();
Some(EncoderInFlight {
raw: mem::replace(&mut self.command_encoder, new_encoder), raw: mem::replace(&mut self.command_encoder, new_encoder),
cmd_buffers: mem::take(&mut self.executing_command_buffers), cmd_buffers: vec![cmd_buf],
trackers: Tracker::new(), trackers: Tracker::new(),
}) }))
} else { } else {
None Ok(None)
} }
} }
@ -1425,14 +1403,17 @@ impl Global {
} }
} }
let refs = pending_writes if let Some(pending_execution) = pending_writes.pre_submit(
.pre_submit()? &device.command_allocator,
.into_iter() device.raw(),
.chain( queue.raw.as_ref().unwrap(),
active_executions )? {
.iter() active_executions.insert(0, pending_execution);
.flat_map(|pool_execution| pool_execution.cmd_buffers.iter()), }
)
let hal_command_buffers = active_executions
.iter()
.flat_map(|e| e.cmd_buffers.iter())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
{ {
@ -1451,19 +1432,16 @@ impl Global {
.raw .raw
.as_ref() .as_ref()
.unwrap() .unwrap()
.submit(&refs, &submit_surface_textures, (fence, submit_index)) .submit(
&hal_command_buffers,
&submit_surface_textures,
(fence, submit_index),
)
.map_err(DeviceError::from)?; .map_err(DeviceError::from)?;
} }
} }
profiling::scope!("cleanup"); profiling::scope!("cleanup");
if let Some(pending_execution) = pending_writes.post_submit(
&device.command_allocator,
device.raw(),
queue.raw.as_ref().unwrap(),
) {
active_executions.push(pending_execution);
}
// this will register the new submission to the life time tracker // this will register the new submission to the life time tracker
let mut pending_write_resources = mem::take(&mut pending_writes.temp_resources); let mut pending_write_resources = mem::take(&mut pending_writes.temp_resources);