Skip to content

Commit

Permalink
[core] Use ManuallyDrop for wgpu_core::device::Queue::raw.
Browse files Browse the repository at this point in the history
Change the field `wgpu_core::device::Queue::raw` from an
`Option<A::Queue>` to a `std::mem::ManuallyDrop<A::Queue>`. Replace
various `.as_ref().unwrap()` chains with calls to a new accessor
function `Queue::raw`.

An `Option` is misleading, as this field is always populated during
the lifetime of a `Queue`. Instead, we simply have a field whose value
needs to be moved in `<Queue as Drop>::drop`; `ManuallyDrop` is the
Rust idiom for this situation.
  • Loading branch information
jimblandy committed Jul 22, 2024
1 parent 205f1e3 commit d2e308d
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 24 deletions.
32 changes: 21 additions & 11 deletions wgpu-core/src/device/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,23 @@ use thiserror::Error;
use super::Device;

pub struct Queue<A: HalApi> {
pub(crate) raw: Option<A::Queue>,
raw: std::mem::ManuallyDrop<A::Queue>,
pub(crate) device: Arc<Device<A>>,
}

impl<A: HalApi> Queue<A> {
pub(crate) fn new(device: Arc<Device<A>>, raw: A::Queue) -> Self {
Queue {
raw: std::mem::ManuallyDrop::new(raw),
device,
}
}

pub(crate) fn raw(&self) -> &A::Queue {
&self.raw
}
}

crate::impl_resource_type!(Queue);
// TODO: https://github.com/gfx-rs/wgpu/issues/4014
impl<A: HalApi> Labeled for Queue<A> {
Expand All @@ -56,7 +69,8 @@ crate::impl_storage_item!(Queue);
impl<A: HalApi> Drop for Queue<A> {
fn drop(&mut self) {
resource_log!("Drop {}", self.error_ident());
let queue = self.raw.take().unwrap();
// Safety: we never access `self.raw` beyond this point.
let queue = unsafe { std::mem::ManuallyDrop::take(&mut self.raw) };
self.device.release_queue(queue);
}
}
Expand Down Expand Up @@ -1272,11 +1286,9 @@ impl Global {
}
}

if let Some(pending_execution) = pending_writes.pre_submit(
&device.command_allocator,
device.raw(),
queue.raw.as_ref().unwrap(),
)? {
if let Some(pending_execution) =
pending_writes.pre_submit(&device.command_allocator, device.raw(), queue.raw())?
{
active_executions.insert(0, pending_execution);
}

Expand All @@ -1298,9 +1310,7 @@ impl Global {

unsafe {
queue
.raw
.as_ref()
.unwrap()
.raw()
.submit(
&hal_command_buffers,
&submit_surface_textures,
Expand Down Expand Up @@ -1356,7 +1366,7 @@ impl Global {
) -> Result<f32, InvalidQueue> {
let hub = A::hub(self);
match hub.queues.get(queue_id) {
Ok(queue) => Ok(unsafe { queue.raw.as_ref().unwrap().get_timestamp_period() }),
Ok(queue) => Ok(unsafe { queue.raw().get_timestamp_period() }),
Err(_) => Err(InvalidQueue),
}
}
Expand Down
2 changes: 1 addition & 1 deletion wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1601,7 +1601,7 @@ impl<A: HalApi> Device<A> {

let encoder = self
.command_allocator
.acquire_encoder(self.raw(), queue.raw.as_ref().unwrap())?;
.acquire_encoder(self.raw(), queue.raw())?;

Ok(command::CommandBuffer::new(
encoder,
Expand Down
6 changes: 1 addition & 5 deletions wgpu-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,7 @@ impl<A: HalApi> Adapter<A> {
instance_flags,
) {
let device = Arc::new(device);
let queue = Queue {
device: device.clone(),
raw: Some(hal_device.queue),
};
let queue = Arc::new(queue);
let queue = Arc::new(Queue::new(device.clone(), hal_device.queue));
device.set_queue(&queue);
return Ok((device, queue));
}
Expand Down
8 changes: 1 addition & 7 deletions wgpu-core/src/present.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,13 +326,7 @@ impl Global {
log::error!("Presented frame is from a different surface");
Err(hal::SurfaceError::Lost)
} else {
unsafe {
queue
.raw
.as_ref()
.unwrap()
.present(suf.unwrap(), raw.take().unwrap())
}
unsafe { queue.raw().present(suf.unwrap(), raw.take().unwrap()) }
}
}
_ => unreachable!(),
Expand Down

0 comments on commit d2e308d

Please sign in to comment.