From 03db77cb8c406245a28edccf7f22c8be8a6c8bbd Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Mon, 8 Apr 2024 18:51:30 -0700 Subject: [PATCH] [core] Replace id `transmute` method with explicit functions. (#5509) Replace the `wgpu_core::id::Id::transmute` method, the `transmute` private module, and the `Transmute` sealed trait with some associated functions with obvious names. --- player/src/bin/play.rs | 2 +- player/src/lib.rs | 14 +++++++---- player/tests/test.rs | 2 +- wgpu-core/src/command/mod.rs | 8 +++---- wgpu-core/src/command/render.rs | 5 +++- wgpu-core/src/device/global.rs | 14 ++++++----- wgpu-core/src/device/queue.rs | 4 ++-- wgpu-core/src/id.rs | 41 +++++++++++++++------------------ wgpu-core/src/resource.rs | 5 +++- wgpu/src/backend/wgpu_core.rs | 8 +++---- 10 files changed, 54 insertions(+), 49 deletions(-) diff --git a/player/src/bin/play.rs b/player/src/bin/play.rs index 7e3cbad11b..5c438dd20d 100644 --- a/player/src/bin/play.rs +++ b/player/src/bin/play.rs @@ -87,7 +87,7 @@ fn main() { &desc, None, Some(id), - Some(id.transmute()) + Some(id.into_queue_id()) )); if let Some(e) = error { panic!("{:?}", e); diff --git a/player/src/lib.rs b/player/src/lib.rs index eb89e43f73..ca3a4b6a57 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -336,7 +336,7 @@ impl GlobalPlay for wgc::global::Global { let bin = std::fs::read(dir.join(data)).unwrap(); let size = (range.end - range.start) as usize; if queued { - self.queue_write_buffer::(device.transmute(), id, range.start, &bin) + self.queue_write_buffer::(device.into_queue_id(), id, range.start, &bin) .unwrap(); } else { self.device_wait_for_buffer::(device, id).unwrap(); @@ -351,23 +351,27 @@ impl GlobalPlay for wgc::global::Global { size, } => { let bin = std::fs::read(dir.join(data)).unwrap(); - self.queue_write_texture::(device.transmute(), &to, &bin, &layout, &size) + self.queue_write_texture::(device.into_queue_id(), &to, &bin, &layout, &size) .unwrap(); } Action::Submit(_index, ref commands) if commands.is_empty() => { - self.queue_submit::(device.transmute(), &[]).unwrap(); + self.queue_submit::(device.into_queue_id(), &[]).unwrap(); } Action::Submit(_index, commands) => { let (encoder, error) = self.device_create_command_encoder::( device, &wgt::CommandEncoderDescriptor { label: None }, - Some(comb_manager.process(device.backend()).transmute()), + Some( + comb_manager + .process(device.backend()) + .into_command_encoder_id(), + ), ); if let Some(e) = error { panic!("{e}"); } let cmdbuf = self.encode_commands::(encoder, commands); - self.queue_submit::(device.transmute(), &[cmdbuf]) + self.queue_submit::(device.into_queue_id(), &[cmdbuf]) .unwrap(); } } diff --git a/player/tests/test.rs b/player/tests/test.rs index c04622b42e..a6c7222b61 100644 --- a/player/tests/test.rs +++ b/player/tests/test.rs @@ -115,7 +115,7 @@ impl Test<'_> { }, None, Some(device_id), - Some(device_id.transmute()) + Some(device_id.into_queue_id()) )); if let Some(e) = error { panic!("{:?}", e); diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index ab413db737..e2e8f74113 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -253,7 +253,7 @@ impl CommandBuffer { id: id::CommandEncoderId, ) -> Result, CommandEncoderError> { let storage = hub.command_buffers.read(); - match storage.get(id.transmute()) { + match storage.get(id.into_command_buffer_id()) { Ok(cmd_buf) => match cmd_buf.data.lock().as_ref().unwrap().status { CommandEncoderStatus::Recording => Ok(cmd_buf.clone()), CommandEncoderStatus::Finished => Err(CommandEncoderError::NotRecording), @@ -418,7 +418,7 @@ impl Global { let hub = A::hub(self); - let error = match hub.command_buffers.get(encoder_id.transmute()) { + let error = match hub.command_buffers.get(encoder_id.into_command_buffer_id()) { Ok(cmd_buf) => { let mut cmd_buf_data = cmd_buf.data.lock(); let cmd_buf_data = cmd_buf_data.as_mut().unwrap(); @@ -444,7 +444,7 @@ impl Global { Err(_) => Some(CommandEncoderError::Invalid), }; - (encoder_id.transmute(), error) + (encoder_id.into_command_buffer_id(), error) } pub fn command_encoder_push_debug_group( @@ -700,7 +700,7 @@ impl PrettyError for PassErrorScope { // This error is not in the error chain, only notes are needed match *self { Self::Pass(id) => { - fmt.command_buffer_label(&id.transmute()); + fmt.command_buffer_label(&id.into_command_buffer_id()); } Self::SetBindGroup(id) => { fmt.bind_group_label(&id); diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 7e859e3cc8..4e887fea2e 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -2409,7 +2409,10 @@ impl Global { (trackers, pending_discard_init_fixups) }; - let cmd_buf = hub.command_buffers.get(encoder_id.transmute()).unwrap(); + let cmd_buf = hub + .command_buffers + .get(encoder_id.into_command_buffer_id()) + .unwrap(); let mut cmd_buf_data = cmd_buf.data.lock(); let cmd_buf_data = cmd_buf_data.as_mut().unwrap(); diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 7f682f5559..9c54dfc193 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -1334,7 +1334,9 @@ impl Global { profiling::scope!("Device::create_command_encoder"); let hub = A::hub(self); - let fid = hub.command_buffers.prepare(id_in.map(|id| id.transmute())); + let fid = hub + .command_buffers + .prepare(id_in.map(|id| id.into_command_buffer_id())); let error = loop { let device = match hub.devices.get(device_id) { @@ -1369,11 +1371,11 @@ impl Global { let (id, _) = fid.assign(Arc::new(command_buffer)); api_log!("Device::create_command_encoder -> {id:?}"); - return (id.transmute(), None); + return (id.into_command_encoder_id(), None); }; let id = fid.assign_error(desc.label.borrow_or_default()); - (id.transmute(), Some(error)) + (id.into_command_encoder_id(), Some(error)) } pub fn command_buffer_label(&self, id: id::CommandBufferId) -> String { @@ -1388,7 +1390,7 @@ impl Global { if let Some(cmd_buf) = hub .command_buffers - .unregister(command_encoder_id.transmute()) + .unregister(command_encoder_id.into_command_buffer_id()) { cmd_buf.data.lock().as_mut().unwrap().encoder.discard(); cmd_buf @@ -1400,7 +1402,7 @@ impl Global { pub fn command_buffer_drop(&self, command_buffer_id: id::CommandBufferId) { profiling::scope!("CommandBuffer::drop"); api_log!("CommandBuffer::drop {command_buffer_id:?}"); - self.command_encoder_drop::(command_buffer_id.transmute()) + self.command_encoder_drop::(command_buffer_id.into_command_encoder_id()) } pub fn device_create_render_bundle_encoder( @@ -2121,7 +2123,7 @@ impl Global { .map_err(|_| DeviceError::Invalid)?; if let wgt::Maintain::WaitForSubmissionIndex(submission_index) = maintain { - if submission_index.queue_id != device_id.transmute() { + if submission_index.queue_id != device_id.into_queue_id() { return Err(WaitIdleError::WrongSubmissionIndex( submission_index.queue_id, device_id, diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 26d6c8b519..0e91408b65 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -707,7 +707,7 @@ impl Global { .get(destination.texture) .map_err(|_| TransferError::InvalidTexture(destination.texture))?; - if dst.device.as_info().id() != queue_id.transmute() { + if dst.device.as_info().id().into_queue_id() != queue_id { return Err(DeviceError::WrongDevice.into()); } @@ -1191,7 +1191,7 @@ impl Global { Err(_) => continue, }; - if cmdbuf.device.as_info().id() != queue_id.transmute() { + if cmdbuf.device.as_info().id().into_queue_id() != queue_id { return Err(DeviceError::WrongDevice.into()); } diff --git a/wgpu-core/src/id.rs b/wgpu-core/src/id.rs index 72b74218d0..c901a97db6 100644 --- a/wgpu-core/src/id.rs +++ b/wgpu-core/src/id.rs @@ -182,15 +182,6 @@ where self.0.backend() } - /// Transmute this identifier to one with a different marker trait. - /// - /// Legal use is governed through a sealed trait, however it's correctness - /// depends on the current implementation of `wgpu-core`. - #[inline] - pub const fn transmute>(self) -> Id { - Id(self.0, PhantomData) - } - #[inline] pub fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self { Id(RawId::zip(index, epoch, backend), PhantomData) @@ -202,20 +193,6 @@ where } } -pub(crate) mod transmute { - // This trait is effectively sealed to prevent illegal transmutes. - pub trait Transmute: super::Marker {} - - // Self-transmute is always legal. - impl Transmute for T where T: super::Marker {} - - // TODO: Remove these once queues have their own identifiers. - impl Transmute for super::markers::Device {} - impl Transmute for super::markers::Queue {} - impl Transmute for super::markers::CommandEncoder {} - impl Transmute for super::markers::CommandBuffer {} -} - impl Copy for Id where T: Marker {} impl Clone for Id @@ -349,6 +326,24 @@ ids! { pub type QuerySetId QuerySet; } +impl CommandEncoderId { + pub fn into_command_buffer_id(self) -> CommandBufferId { + Id(self.0, PhantomData) + } +} + +impl CommandBufferId { + pub fn into_command_encoder_id(self) -> CommandEncoderId { + Id(self.0, PhantomData) + } +} + +impl DeviceId { + pub fn into_queue_id(self) -> QueueId { + Id(self.0, PhantomData) + } +} + #[test] fn test_id_backend() { for &b in &[ diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 8256b95539..62335304c4 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -1043,7 +1043,10 @@ impl Global { profiling::scope!("CommandEncoder::as_hal"); let hub = A::hub(self); - let cmd_buf = hub.command_buffers.get(id.transmute()).unwrap(); + let cmd_buf = hub + .command_buffers + .get(id.into_command_buffer_id()) + .unwrap(); let mut cmd_buf_data = cmd_buf.data.lock(); let cmd_buf_data = cmd_buf_data.as_mut().unwrap(); let cmd_buf_raw = cmd_buf_data.encoder.open().ok(); diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index c73b0fbd1d..edc24cee38 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -631,7 +631,7 @@ impl crate::Context for ContextWgpuCore { id: queue_id, error_sink, }; - ready(Ok((device_id, device, device_id.transmute(), queue))) + ready(Ok((device_id, device, device_id.into_queue_id(), queue))) } fn instance_poll_all_devices(&self, force_wait: bool) -> bool { @@ -1839,8 +1839,7 @@ impl crate::Context for ContextWgpuCore { if let Err(cause) = wgc::gfx_select!( encoder => self.0.command_encoder_run_compute_pass(*encoder, pass_data) ) { - let name = - wgc::gfx_select!(encoder => self.0.command_buffer_label(encoder.transmute())); + let name = wgc::gfx_select!(encoder => self.0.command_buffer_label(encoder.into_command_buffer_id())); self.handle_error( &encoder_data.error_sink, cause, @@ -1923,8 +1922,7 @@ impl crate::Context for ContextWgpuCore { if let Err(cause) = wgc::gfx_select!(encoder => self.0.command_encoder_run_render_pass(*encoder, pass_data)) { - let name = - wgc::gfx_select!(encoder => self.0.command_buffer_label(encoder.transmute())); + let name = wgc::gfx_select!(encoder => self.0.command_buffer_label(encoder.into_command_buffer_id())); self.handle_error( &encoder_data.error_sink, cause,