use ManuallyDrop for remaining resources

This commit is contained in:
teoxoy 2024-08-07 14:24:52 +02:00 committed by Teodor Tanasoaia
parent b0cc0d2ebc
commit c1bc0864c5
5 changed files with 101 additions and 93 deletions

View File

@ -26,6 +26,7 @@ use serde::Serialize;
use std::{ use std::{
borrow::Cow, borrow::Cow,
mem::ManuallyDrop,
ops::Range, ops::Range,
sync::{Arc, Weak}, sync::{Arc, Weak},
}; };
@ -498,7 +499,7 @@ impl<A: HalApi> std::fmt::Display for ExclusivePipeline<A> {
/// Bind group layout. /// Bind group layout.
#[derive(Debug)] #[derive(Debug)]
pub struct BindGroupLayout<A: HalApi> { pub struct BindGroupLayout<A: HalApi> {
pub(crate) raw: Option<A::BindGroupLayout>, pub(crate) raw: ManuallyDrop<A::BindGroupLayout>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) entries: bgl::EntryMap, pub(crate) entries: bgl::EntryMap,
/// It is very important that we know if the bind group comes from the BGL pool. /// It is very important that we know if the bind group comes from the BGL pool.
@ -517,15 +518,15 @@ pub struct BindGroupLayout<A: HalApi> {
impl<A: HalApi> Drop for BindGroupLayout<A> { impl<A: HalApi> Drop for BindGroupLayout<A> {
fn drop(&mut self) { fn drop(&mut self) {
resource_log!("Destroy raw {}", self.error_ident());
if matches!(self.origin, bgl::Origin::Pool) { if matches!(self.origin, bgl::Origin::Pool) {
self.device.bgl_pool.remove(&self.entries); self.device.bgl_pool.remove(&self.entries);
} }
if let Some(raw) = self.raw.take() { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
resource_log!("Destroy raw {}", self.error_ident()); let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device; use hal::Device;
self.device.raw().destroy_bind_group_layout(raw); self.device.raw().destroy_bind_group_layout(raw);
}
} }
} }
} }
@ -537,7 +538,7 @@ crate::impl_storage_item!(BindGroupLayout);
impl<A: HalApi> BindGroupLayout<A> { impl<A: HalApi> BindGroupLayout<A> {
pub(crate) fn raw(&self) -> &A::BindGroupLayout { pub(crate) fn raw(&self) -> &A::BindGroupLayout {
self.raw.as_ref().unwrap() &self.raw
} }
} }
@ -651,7 +652,7 @@ pub struct ResolvedPipelineLayoutDescriptor<'a, A: HalApi> {
#[derive(Debug)] #[derive(Debug)]
pub struct PipelineLayout<A: HalApi> { pub struct PipelineLayout<A: HalApi> {
pub(crate) raw: Option<A::PipelineLayout>, pub(crate) raw: ManuallyDrop<A::PipelineLayout>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
pub(crate) label: String, pub(crate) label: String,
@ -661,19 +662,19 @@ pub struct PipelineLayout<A: HalApi> {
impl<A: HalApi> Drop for PipelineLayout<A> { impl<A: HalApi> Drop for PipelineLayout<A> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident());
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
unsafe { let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
use hal::Device; unsafe {
self.device.raw().destroy_pipeline_layout(raw); use hal::Device;
} self.device.raw().destroy_pipeline_layout(raw);
} }
} }
} }
impl<A: HalApi> PipelineLayout<A> { impl<A: HalApi> PipelineLayout<A> {
pub(crate) fn raw(&self) -> &A::PipelineLayout { pub(crate) fn raw(&self) -> &A::PipelineLayout {
self.raw.as_ref().unwrap() &self.raw
} }
pub(crate) fn get_binding_maps(&self) -> ArrayVec<&bgl::EntryMap, { hal::MAX_BIND_GROUPS }> { pub(crate) fn get_binding_maps(&self) -> ArrayVec<&bgl::EntryMap, { hal::MAX_BIND_GROUPS }> {

View File

@ -2191,23 +2191,21 @@ impl Global {
if !cache.device.is_valid() { if !cache.device.is_valid() {
return None; return None;
} }
if let Some(raw_cache) = cache.raw.as_ref() { let mut vec = unsafe { cache.device.raw().pipeline_cache_get_data(cache.raw()) }?;
let mut vec = unsafe { cache.device.raw().pipeline_cache_get_data(raw_cache) }?; let validation_key = cache.device.raw().pipeline_cache_validation_key()?;
let validation_key = cache.device.raw().pipeline_cache_validation_key()?;
let mut header_contents = [0; pipeline_cache::HEADER_LENGTH]; let mut header_contents = [0; pipeline_cache::HEADER_LENGTH];
pipeline_cache::add_cache_header( pipeline_cache::add_cache_header(
&mut header_contents, &mut header_contents,
&vec, &vec,
&cache.device.adapter.raw.info, &cache.device.adapter.raw.info,
validation_key, validation_key,
); );
let deleted = vec.splice(..0, header_contents).collect::<Vec<_>>(); let deleted = vec.splice(..0, header_contents).collect::<Vec<_>>();
debug_assert!(deleted.is_empty()); debug_assert!(deleted.is_empty());
return Some(vec); return Some(vec);
}
} }
None None
} }

View File

@ -80,7 +80,7 @@ use super::{
/// When locking pending_writes please check that trackers is not locked /// When locking pending_writes please check that trackers is not locked
/// trackers should be locked only when needed for the shortest time possible /// trackers should be locked only when needed for the shortest time possible
pub struct Device<A: HalApi> { pub struct Device<A: HalApi> {
raw: Option<A::Device>, raw: ManuallyDrop<A::Device>,
pub(crate) adapter: Arc<Adapter<A>>, pub(crate) adapter: Arc<Adapter<A>>,
pub(crate) queue: OnceCell<Weak<Queue<A>>>, pub(crate) queue: OnceCell<Weak<Queue<A>>>,
queue_to_drop: OnceCell<A::Queue>, queue_to_drop: OnceCell<A::Queue>,
@ -169,7 +169,8 @@ impl<A: HalApi> std::fmt::Debug for Device<A> {
impl<A: HalApi> Drop for Device<A> { impl<A: HalApi> Drop for Device<A> {
fn drop(&mut self) { fn drop(&mut self) {
resource_log!("Drop {}", self.error_ident()); resource_log!("Drop {}", self.error_ident());
let raw = self.raw.take().unwrap(); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
// SAFETY: We are in the Drop impl and we don't use self.pending_writes anymore after this point. // SAFETY: We are in the Drop impl and we don't use self.pending_writes anymore after this point.
let pending_writes = unsafe { ManuallyDrop::take(&mut self.pending_writes.lock()) }; let pending_writes = unsafe { ManuallyDrop::take(&mut self.pending_writes.lock()) };
pending_writes.dispose(&raw); pending_writes.dispose(&raw);
@ -193,7 +194,7 @@ pub enum CreateDeviceError {
impl<A: HalApi> Device<A> { impl<A: HalApi> Device<A> {
pub(crate) fn raw(&self) -> &A::Device { pub(crate) fn raw(&self) -> &A::Device {
self.raw.as_ref().unwrap() &self.raw
} }
pub(crate) fn require_features(&self, feature: wgt::Features) -> Result<(), MissingFeatures> { pub(crate) fn require_features(&self, feature: wgt::Features) -> Result<(), MissingFeatures> {
if self.features.contains(feature) { if self.features.contains(feature) {
@ -271,7 +272,7 @@ impl<A: HalApi> Device<A> {
let downlevel = adapter.raw.capabilities.downlevel.clone(); let downlevel = adapter.raw.capabilities.downlevel.clone();
Ok(Self { Ok(Self {
raw: Some(raw_device), raw: ManuallyDrop::new(raw_device),
adapter: adapter.clone(), adapter: adapter.clone(),
queue: OnceCell::new(), queue: OnceCell::new(),
queue_to_drop: OnceCell::new(), queue_to_drop: OnceCell::new(),
@ -1418,7 +1419,7 @@ impl<A: HalApi> Device<A> {
}; };
let sampler = Sampler { let sampler = Sampler {
raw: Some(raw), raw: ManuallyDrop::new(raw),
device: self.clone(), device: self.clone(),
label: desc.label.to_string(), label: desc.label.to_string(),
tracking_data: TrackingData::new(self.tracker_indices.samplers.clone()), tracking_data: TrackingData::new(self.tracker_indices.samplers.clone()),
@ -1550,7 +1551,7 @@ impl<A: HalApi> Device<A> {
}; };
let module = pipeline::ShaderModule { let module = pipeline::ShaderModule {
raw: Some(raw), raw: ManuallyDrop::new(raw),
device: self.clone(), device: self.clone(),
interface: Some(interface), interface: Some(interface),
label: desc.label.to_string(), label: desc.label.to_string(),
@ -1591,7 +1592,7 @@ impl<A: HalApi> Device<A> {
}; };
let module = pipeline::ShaderModule { let module = pipeline::ShaderModule {
raw: Some(raw), raw: ManuallyDrop::new(raw),
device: self.clone(), device: self.clone(),
interface: None, interface: None,
label: desc.label.to_string(), label: desc.label.to_string(),
@ -1861,7 +1862,7 @@ impl<A: HalApi> Device<A> {
.map_err(binding_model::CreateBindGroupLayoutError::TooManyBindings)?; .map_err(binding_model::CreateBindGroupLayoutError::TooManyBindings)?;
let bgl = BindGroupLayout { let bgl = BindGroupLayout {
raw: Some(raw), raw: ManuallyDrop::new(raw),
device: self.clone(), device: self.clone(),
entries: entry_map, entries: entry_map,
origin, origin,
@ -2576,7 +2577,7 @@ impl<A: HalApi> Device<A> {
drop(raw_bind_group_layouts); drop(raw_bind_group_layouts);
let layout = binding_model::PipelineLayout { let layout = binding_model::PipelineLayout {
raw: Some(raw), raw: ManuallyDrop::new(raw),
device: self.clone(), device: self.clone(),
label: desc.label.to_string(), label: desc.label.to_string(),
bind_group_layouts, bind_group_layouts,
@ -2718,7 +2719,7 @@ impl<A: HalApi> Device<A> {
constants: desc.stage.constants.as_ref(), constants: desc.stage.constants.as_ref(),
zero_initialize_workgroup_memory: desc.stage.zero_initialize_workgroup_memory, zero_initialize_workgroup_memory: desc.stage.zero_initialize_workgroup_memory,
}, },
cache: cache.as_ref().and_then(|it| it.raw.as_ref()), cache: cache.as_ref().map(|it| it.raw()),
}; };
let raw = let raw =
@ -2742,7 +2743,7 @@ impl<A: HalApi> Device<A> {
)?; )?;
let pipeline = pipeline::ComputePipeline { let pipeline = pipeline::ComputePipeline {
raw: Some(raw), raw: ManuallyDrop::new(raw),
layout: pipeline_layout, layout: pipeline_layout,
device: self.clone(), device: self.clone(),
_shader_module: shader_module, _shader_module: shader_module,
@ -3299,7 +3300,7 @@ impl<A: HalApi> Device<A> {
fragment_stage, fragment_stage,
color_targets, color_targets,
multiview: desc.multiview, multiview: desc.multiview,
cache: cache.as_ref().and_then(|it| it.raw.as_ref()), cache: cache.as_ref().map(|it| it.raw()),
}; };
let raw = let raw =
unsafe { self.raw().create_render_pipeline(&pipeline_desc) }.map_err( unsafe { self.raw().create_render_pipeline(&pipeline_desc) }.map_err(
@ -3363,7 +3364,7 @@ impl<A: HalApi> Device<A> {
}; };
let pipeline = pipeline::RenderPipeline { let pipeline = pipeline::RenderPipeline {
raw: Some(raw), raw: ManuallyDrop::new(raw),
layout: pipeline_layout, layout: pipeline_layout,
device: self.clone(), device: self.clone(),
pass_context, pass_context,
@ -3434,7 +3435,7 @@ impl<A: HalApi> Device<A> {
device: self.clone(), device: self.clone(),
label: desc.label.to_string(), label: desc.label.to_string(),
// This would be none in the error condition, which we don't implement yet // This would be none in the error condition, which we don't implement yet
raw: Some(raw), raw: ManuallyDrop::new(raw),
}; };
let cache = Arc::new(cache); let cache = Arc::new(cache);
@ -3535,8 +3536,10 @@ impl<A: HalApi> Device<A> {
let hal_desc = desc.map_label(|label| label.to_hal(self.instance_flags)); let hal_desc = desc.map_label(|label| label.to_hal(self.instance_flags));
let raw = unsafe { self.raw().create_query_set(&hal_desc).unwrap() };
let query_set = QuerySet { let query_set = QuerySet {
raw: Some(unsafe { self.raw().create_query_set(&hal_desc).unwrap() }), raw: ManuallyDrop::new(raw),
device: self.clone(), device: self.clone(),
label: desc.label.to_string(), label: desc.label.to_string(),
tracking_data: TrackingData::new(self.tracker_indices.query_sets.clone()), tracking_data: TrackingData::new(self.tracker_indices.query_sets.clone()),

View File

@ -10,7 +10,7 @@ use crate::{
}; };
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use naga::error::ShaderError; use naga::error::ShaderError;
use std::{borrow::Cow, marker::PhantomData, num::NonZeroU32, sync::Arc}; use std::{borrow::Cow, marker::PhantomData, mem::ManuallyDrop, num::NonZeroU32, sync::Arc};
use thiserror::Error; use thiserror::Error;
/// Information about buffer bindings, which /// Information about buffer bindings, which
@ -47,7 +47,7 @@ pub struct ShaderModuleDescriptor<'a> {
#[derive(Debug)] #[derive(Debug)]
pub struct ShaderModule<A: HalApi> { pub struct ShaderModule<A: HalApi> {
pub(crate) raw: Option<A::ShaderModule>, pub(crate) raw: ManuallyDrop<A::ShaderModule>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) interface: Option<validation::Interface>, pub(crate) interface: Option<validation::Interface>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
@ -56,12 +56,12 @@ pub struct ShaderModule<A: HalApi> {
impl<A: HalApi> Drop for ShaderModule<A> { impl<A: HalApi> Drop for ShaderModule<A> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident());
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
unsafe { let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
use hal::Device; unsafe {
self.device.raw().destroy_shader_module(raw); use hal::Device;
} self.device.raw().destroy_shader_module(raw);
} }
} }
} }
@ -73,7 +73,7 @@ crate::impl_storage_item!(ShaderModule);
impl<A: HalApi> ShaderModule<A> { impl<A: HalApi> ShaderModule<A> {
pub(crate) fn raw(&self) -> &A::ShaderModule { pub(crate) fn raw(&self) -> &A::ShaderModule {
self.raw.as_ref().unwrap() &self.raw
} }
pub(crate) fn finalize_entry_point_name( pub(crate) fn finalize_entry_point_name(
@ -242,7 +242,7 @@ pub enum CreateComputePipelineError {
#[derive(Debug)] #[derive(Debug)]
pub struct ComputePipeline<A: HalApi> { pub struct ComputePipeline<A: HalApi> {
pub(crate) raw: Option<A::ComputePipeline>, pub(crate) raw: ManuallyDrop<A::ComputePipeline>,
pub(crate) layout: Arc<PipelineLayout<A>>, pub(crate) layout: Arc<PipelineLayout<A>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) _shader_module: Arc<ShaderModule<A>>, pub(crate) _shader_module: Arc<ShaderModule<A>>,
@ -254,12 +254,12 @@ pub struct ComputePipeline<A: HalApi> {
impl<A: HalApi> Drop for ComputePipeline<A> { impl<A: HalApi> Drop for ComputePipeline<A> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident());
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
unsafe { let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
use hal::Device; unsafe {
self.device.raw().destroy_compute_pipeline(raw); use hal::Device;
} self.device.raw().destroy_compute_pipeline(raw);
} }
} }
} }
@ -272,7 +272,7 @@ crate::impl_trackable!(ComputePipeline);
impl<A: HalApi> ComputePipeline<A> { impl<A: HalApi> ComputePipeline<A> {
pub(crate) fn raw(&self) -> &A::ComputePipeline { pub(crate) fn raw(&self) -> &A::ComputePipeline {
self.raw.as_ref().unwrap() &self.raw
} }
} }
@ -301,7 +301,7 @@ impl From<hal::PipelineCacheError> for CreatePipelineCacheError {
#[derive(Debug)] #[derive(Debug)]
pub struct PipelineCache<A: HalApi> { pub struct PipelineCache<A: HalApi> {
pub(crate) raw: Option<A::PipelineCache>, pub(crate) raw: ManuallyDrop<A::PipelineCache>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
pub(crate) label: String, pub(crate) label: String,
@ -309,12 +309,12 @@ pub struct PipelineCache<A: HalApi> {
impl<A: HalApi> Drop for PipelineCache<A> { impl<A: HalApi> Drop for PipelineCache<A> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident());
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
unsafe { let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
use hal::Device; unsafe {
self.device.raw().destroy_pipeline_cache(raw); use hal::Device;
} self.device.raw().destroy_pipeline_cache(raw);
} }
} }
} }
@ -324,6 +324,12 @@ crate::impl_labeled!(PipelineCache);
crate::impl_parent_device!(PipelineCache); crate::impl_parent_device!(PipelineCache);
crate::impl_storage_item!(PipelineCache); crate::impl_storage_item!(PipelineCache);
impl<A: HalApi> PipelineCache<A> {
pub(crate) fn raw(&self) -> &A::PipelineCache {
&self.raw
}
}
/// Describes how the vertex buffer is interpreted. /// Describes how the vertex buffer is interpreted.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@ -586,7 +592,7 @@ impl Default for VertexStep {
#[derive(Debug)] #[derive(Debug)]
pub struct RenderPipeline<A: HalApi> { pub struct RenderPipeline<A: HalApi> {
pub(crate) raw: Option<A::RenderPipeline>, pub(crate) raw: ManuallyDrop<A::RenderPipeline>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) layout: Arc<PipelineLayout<A>>, pub(crate) layout: Arc<PipelineLayout<A>>,
pub(crate) _shader_modules: pub(crate) _shader_modules:
@ -603,12 +609,12 @@ pub struct RenderPipeline<A: HalApi> {
impl<A: HalApi> Drop for RenderPipeline<A> { impl<A: HalApi> Drop for RenderPipeline<A> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident());
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
unsafe { let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
use hal::Device; unsafe {
self.device.raw().destroy_render_pipeline(raw); use hal::Device;
} self.device.raw().destroy_render_pipeline(raw);
} }
} }
} }
@ -621,6 +627,6 @@ crate::impl_trackable!(RenderPipeline);
impl<A: HalApi> RenderPipeline<A> { impl<A: HalApi> RenderPipeline<A> {
pub(crate) fn raw(&self) -> &A::RenderPipeline { pub(crate) fn raw(&self) -> &A::RenderPipeline {
self.raw.as_ref().unwrap() &self.raw
} }
} }

View File

@ -1697,7 +1697,7 @@ pub struct SamplerDescriptor<'a> {
#[derive(Debug)] #[derive(Debug)]
pub struct Sampler<A: HalApi> { pub struct Sampler<A: HalApi> {
pub(crate) raw: Option<A::Sampler>, pub(crate) raw: ManuallyDrop<A::Sampler>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
pub(crate) label: String, pub(crate) label: String,
@ -1710,19 +1710,19 @@ pub struct Sampler<A: HalApi> {
impl<A: HalApi> Drop for Sampler<A> { impl<A: HalApi> Drop for Sampler<A> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident());
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
unsafe { let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
use hal::Device; unsafe {
self.device.raw().destroy_sampler(raw); use hal::Device;
} self.device.raw().destroy_sampler(raw);
} }
} }
} }
impl<A: HalApi> Sampler<A> { impl<A: HalApi> Sampler<A> {
pub(crate) fn raw(&self) -> &A::Sampler { pub(crate) fn raw(&self) -> &A::Sampler {
self.raw.as_ref().unwrap() &self.raw
} }
} }
@ -1793,7 +1793,7 @@ pub type QuerySetDescriptor<'a> = wgt::QuerySetDescriptor<Label<'a>>;
#[derive(Debug)] #[derive(Debug)]
pub struct QuerySet<A: HalApi> { pub struct QuerySet<A: HalApi> {
pub(crate) raw: Option<A::QuerySet>, pub(crate) raw: ManuallyDrop<A::QuerySet>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
pub(crate) label: String, pub(crate) label: String,
@ -1803,12 +1803,12 @@ pub struct QuerySet<A: HalApi> {
impl<A: HalApi> Drop for QuerySet<A> { impl<A: HalApi> Drop for QuerySet<A> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident());
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
unsafe { let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
use hal::Device; unsafe {
self.device.raw().destroy_query_set(raw); use hal::Device;
} self.device.raw().destroy_query_set(raw);
} }
} }
} }
@ -1821,7 +1821,7 @@ crate::impl_trackable!(QuerySet);
impl<A: HalApi> QuerySet<A> { impl<A: HalApi> QuerySet<A> {
pub(crate) fn raw(&self) -> &A::QuerySet { pub(crate) fn raw(&self) -> &A::QuerySet {
self.raw.as_ref().unwrap() &self.raw
} }
} }