diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index f7d032f92..e79a76ee2 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -4018,40 +4018,32 @@ impl Global { let hub = B::hub(self); let mut token = Token::root(); + let fid = hub.render_pipelines.prepare(id_in); let (device_guard, mut token) = hub.devices.read(&mut token); let error = loop { let device = match device_guard.get(device_id) { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; - let (pipeline, derived_bind_group_count, layout_id) = match device + #[cfg(feature = "trace")] + if let Some(ref trace) = device.trace { + trace + .lock() + .add(trace::Action::CreateRenderPipeline(fid.id(), desc.clone())); + } + + let (pipeline, derived_bind_group_count, _layout_id) = match device .create_render_pipeline(device_id, desc, implicit_pipeline_ids, &hub, &mut token) { Ok(pair) => pair, Err(e) => break e, }; - let id = hub - .render_pipelines - .register_identity(id_in, pipeline, &mut token); - - #[cfg(feature = "trace")] - if let Some(ref trace) = device.trace { - trace.lock().add(trace::Action::CreateRenderPipeline( - id.0, - pipeline::RenderPipelineDescriptor { - layout: Some(layout_id), - ..desc.clone() - }, - )); - } - let _ = layout_id; + let id = fid.assign(pipeline, &mut token); return (id.0, derived_bind_group_count, None); }; - let id = - hub.render_pipelines - .register_error(id_in, desc.label.borrow_or_default(), &mut token); + let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); (id, 0, Some(error)) } @@ -4149,40 +4141,32 @@ impl Global { let hub = B::hub(self); let mut token = Token::root(); + let fid = hub.compute_pipelines.prepare(id_in); let (device_guard, mut token) = hub.devices.read(&mut token); let error = loop { let device = match device_guard.get(device_id) { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; - let (pipeline, derived_bind_group_count, layout_id) = match device + #[cfg(feature = "trace")] + if let Some(ref trace) = device.trace { + trace + .lock() + .add(trace::Action::CreateComputePipeline(fid.id(), desc.clone())); + } + + let (pipeline, derived_bind_group_count, _layout_id) = match device .create_compute_pipeline(device_id, desc, implicit_pipeline_ids, &hub, &mut token) { Ok(pair) => pair, Err(e) => break e, }; - let id = hub - .compute_pipelines - .register_identity(id_in, pipeline, &mut token); - - #[cfg(feature = "trace")] - if let Some(ref trace) = device.trace { - trace.lock().add(trace::Action::CreateComputePipeline( - id.0, - pipeline::ComputePipelineDescriptor { - layout: Some(layout_id), - ..desc.clone() - }, - )); - } - let _ = layout_id; + let id = fid.assign(pipeline, &mut token); return (id.0, derived_bind_group_count, None); }; - let id = - hub.compute_pipelines - .register_error(id_in, desc.label.borrow_or_default(), &mut token); + let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); (id, 0, Some(error)) } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index a25f7f788..0760c6640 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -439,10 +439,37 @@ impl> Registry { } } +#[must_use] +pub(crate) struct FutureId<'a, I: TypedId, T> { + id: I, + data: &'a RwLock>, +} + +impl FutureId<'_, I, T> { + pub fn id(&self) -> I { + self.id + } + + pub fn assign<'a, A: Access>(self, value: T, _: &'a mut Token) -> Valid { + self.data.write().insert(self.id, value); + Valid(self.id) + } + + pub fn assign_error<'a, A: Access>(self, label: &str, _: &'a mut Token) -> I { + self.data.write().insert_error(self.id, label); + self.id + } +} + impl> Registry { - pub fn register>(&self, id: I, value: T, _token: &mut Token) { - debug_assert_eq!(id.unzip().2, self.backend); - self.data.write().insert(id, value); + pub(crate) fn prepare( + &self, + id_in: >::Input, + ) -> FutureId { + FutureId { + id: self.identity.process(id_in, self.backend), + data: &self.data, + } } pub fn read<'a, A: Access>( @@ -459,15 +486,14 @@ impl> Registry>( &self, id_in: >::Input, value: T, token: &mut Token, ) -> Valid { - let id = self.identity.process(id_in, self.backend); - self.register(id, value, token); - Valid(id) + self.prepare(id_in).assign(value, token) } pub(crate) fn register_identity_locked( @@ -481,16 +507,14 @@ impl> Registry>( &self, id_in: >::Input, label: &str, - _token: &mut Token, + token: &mut Token, ) -> I { - let id = self.identity.process(id_in, self.backend); - debug_assert_eq!(id.unzip().2, self.backend); - self.data.write().insert_error(id, label); - id + self.prepare(id_in).assign_error(label, token) } pub fn unregister_locked(&self, id: I, guard: &mut Storage) -> Option { @@ -513,10 +537,6 @@ impl> Registry>::Input) -> I { - self.identity.process(id_in, self.backend) - } - pub fn free_id(&self, id: I) { self.identity.free(id) }