Avoid allocating during queue submit (#4947)

This commit is contained in:
John-John Tedro
2024-01-03 19:39:15 +01:00
committed by GitHub
parent 6fdec5cc6b
commit 71762a590c
4 changed files with 29 additions and 38 deletions

View File

@@ -3042,13 +3042,11 @@ impl crate::Context for Context {
wgpu_render_pass_end_pipeline_statistics_query(pass_data)
}
fn render_pass_execute_bundles<'a>(
fn render_pass_execute_bundles(
&self,
_pass: &mut Self::RenderPassId,
pass_data: &mut Self::RenderPassData,
render_bundles: Box<
dyn Iterator<Item = (Self::RenderBundleId, &'a Self::RenderBundleData)> + 'a,
>,
render_bundles: &mut dyn Iterator<Item = (Self::RenderBundleId, &Self::RenderBundleData)>,
) {
let temp_render_bundles = render_bundles.map(|(i, _)| i).collect::<SmallVec<[_; 4]>>();
unsafe {

View File

@@ -3424,13 +3424,11 @@ impl crate::context::Context for Context {
// Not available in gecko yet
}
fn render_pass_execute_bundles<'a>(
fn render_pass_execute_bundles(
&self,
_pass: &mut Self::RenderPassId,
pass_data: &mut Self::RenderPassData,
render_bundles: Box<
dyn Iterator<Item = (Self::RenderBundleId, &'a Self::RenderBundleData)> + 'a,
>,
render_bundles: &mut dyn Iterator<Item = (Self::RenderBundleId, &Self::RenderBundleData)>,
) {
let mapped = render_bundles
.map(|(_, bundle_data)| &bundle_data.0)

View File

@@ -1015,13 +1015,11 @@ pub trait Context: Debug + WasmNotSendSync + Sized {
pass: &mut Self::RenderPassId,
pass_data: &mut Self::RenderPassData,
);
fn render_pass_execute_bundles<'a>(
fn render_pass_execute_bundles(
&self,
pass: &mut Self::RenderPassId,
pass_data: &mut Self::RenderPassData,
render_bundles: Box<
dyn Iterator<Item = (Self::RenderBundleId, &'a Self::RenderBundleData)> + 'a,
>,
render_bundles: &mut dyn Iterator<Item = (Self::RenderBundleId, &Self::RenderBundleData)>,
);
}
@@ -1576,11 +1574,11 @@ pub(crate) trait DynContext: Debug + WasmNotSendSync {
dest: crate::ImageCopyTextureTagged<'_>,
size: wgt::Extent3d,
);
fn queue_submit<'a>(
fn queue_submit(
&self,
queue: &ObjectId,
queue_data: &crate::Data,
command_buffers: Box<dyn Iterator<Item = (ObjectId, Box<crate::Data>)> + 'a>,
command_buffers: &mut dyn Iterator<Item = (ObjectId, Box<crate::Data>)>,
) -> (ObjectId, Arc<crate::Data>);
fn queue_get_timestamp_period(&self, queue: &ObjectId, queue_data: &crate::Data) -> f32;
fn queue_on_submitted_work_done(
@@ -1984,11 +1982,11 @@ pub(crate) trait DynContext: Debug + WasmNotSendSync {
pass: &mut ObjectId,
pass_data: &mut crate::Data,
);
fn render_pass_execute_bundles<'a>(
fn render_pass_execute_bundles(
&self,
pass: &mut ObjectId,
pass_data: &mut crate::Data,
render_bundles: Box<dyn Iterator<Item = (&'a ObjectId, &'a crate::Data)> + 'a>,
render_bundles: &mut dyn Iterator<Item = (&ObjectId, &crate::Data)>,
);
}
@@ -3025,15 +3023,15 @@ where
Context::queue_copy_external_image_to_texture(self, &queue, queue_data, source, dest, size)
}
fn queue_submit<'a>(
fn queue_submit(
&self,
queue: &ObjectId,
queue_data: &crate::Data,
command_buffers: Box<dyn Iterator<Item = (ObjectId, Box<crate::Data>)> + 'a>,
command_buffers: &mut dyn Iterator<Item = (ObjectId, Box<crate::Data>)>,
) -> (ObjectId, Arc<crate::Data>) {
let queue = <T::QueueId>::from(*queue);
let queue_data = downcast_ref(queue_data);
let command_buffers = command_buffers.into_iter().map(|(id, data)| {
let command_buffers = command_buffers.map(|(id, data)| {
let command_buffer_data: <T as Context>::CommandBufferData = *data.downcast().unwrap();
(<T::CommandBufferId>::from(id), command_buffer_data)
});
@@ -3986,19 +3984,19 @@ where
Context::render_pass_end_pipeline_statistics_query(self, &mut pass, pass_data)
}
fn render_pass_execute_bundles<'a>(
fn render_pass_execute_bundles(
&self,
pass: &mut ObjectId,
pass_data: &mut crate::Data,
render_bundles: Box<dyn Iterator<Item = (&'a ObjectId, &'a crate::Data)> + 'a>,
render_bundles: &mut dyn Iterator<Item = (&ObjectId, &crate::Data)>,
) {
let mut pass = <T::RenderPassId>::from(*pass);
let pass_data = downcast_mut::<T::RenderPassData>(pass_data);
let render_bundles = Box::new(render_bundles.into_iter().map(|(id, data)| {
let mut render_bundles = render_bundles.map(|(id, data)| {
let render_bundle_data: &<T as Context>::RenderBundleData = downcast_ref(data);
(<T::RenderBundleId>::from(*id), render_bundle_data)
}));
Context::render_pass_execute_bundles(self, &mut pass, pass_data, render_bundles)
});
Context::render_pass_execute_bundles(self, &mut pass, pass_data, &mut render_bundles)
}
}

View File

@@ -3729,19 +3729,16 @@ impl<'a> RenderPass<'a> {
///
/// Commands in the bundle do not inherit this render pass's current render state, and after the
/// bundle has executed, the state is **cleared** (reset to defaults, not the previous state).
pub fn execute_bundles<I: IntoIterator<Item = &'a RenderBundle> + 'a>(
&mut self,
render_bundles: I,
) {
pub fn execute_bundles<I: IntoIterator<Item = &'a RenderBundle>>(&mut self, render_bundles: I) {
let mut render_bundles = render_bundles
.into_iter()
.map(|rb| (&rb.id, rb.data.as_ref()));
DynContext::render_pass_execute_bundles(
&*self.parent.context,
&mut self.id,
self.data.as_mut(),
Box::new(
render_bundles
.into_iter()
.map(|rb| (&rb.id, rb.data.as_ref())),
),
&mut render_bundles,
)
}
}
@@ -4609,15 +4606,15 @@ impl Queue {
&self,
command_buffers: I,
) -> SubmissionIndex {
let mut command_buffers = command_buffers
.into_iter()
.map(|mut comb| (comb.id.take().unwrap(), comb.data.take().unwrap()));
let (raw, data) = DynContext::queue_submit(
&*self.context,
&self.id,
self.data.as_ref(),
Box::new(
command_buffers
.into_iter()
.map(|mut comb| (comb.id.take().unwrap(), comb.data.take().unwrap())),
),
&mut command_buffers,
);
SubmissionIndex(raw, data)