From c90f43bc2ad6b2b8d462e36047935967998c9763 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Thu, 11 Jan 2024 06:48:25 +0100 Subject: [PATCH] Move the trace recording of destroy events out of triage_resources (#5036) --- wgpu-core/src/binding_model.rs | 19 +++ wgpu-core/src/command/bundle.rs | 14 ++ wgpu-core/src/device/global.rs | 6 +- wgpu-core/src/device/life.rs | 214 ++++--------------------------- wgpu-core/src/device/resource.rs | 6 +- wgpu-core/src/pipeline.rs | 16 ++- wgpu-core/src/resource.rs | 45 ++++++- 7 files changed, 117 insertions(+), 203 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index ec97568f0c..39a21f7a13 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "trace")] +use crate::device::trace; use crate::{ device::{ bgl, Device, DeviceError, MissingDownlevelFlags, MissingFeatures, SHADER_STAGE_COUNT, @@ -469,6 +471,11 @@ impl Drop for BindGroupLayout { self.device.bgl_pool.remove(&self.entries); } if let Some(raw) = self.raw.take() { + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyBindGroupLayout(self.info.id())); + } + resource_log!("Destroy raw BindGroupLayout {:?}", self.info.label()); unsafe { use hal::Device; @@ -608,6 +615,12 @@ impl Drop for PipelineLayout { fn drop(&mut self) { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw PipelineLayout {:?}", self.info.label()); + + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyPipelineLayout(self.info.id())); + } + unsafe { use hal::Device; self.device.raw().destroy_pipeline_layout(raw); @@ -837,6 +850,12 @@ impl Drop for BindGroup { fn drop(&mut self) { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw BindGroup {:?}", self.info.label()); + + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyBindGroup(self.info.id())); + } + unsafe { use hal::Device; self.device.raw().destroy_bind_group(raw); diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 4500ca99f3..0cb9394a78 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -78,6 +78,8 @@ index format changes. #![allow(clippy::reversed_empty_ranges)] +#[cfg(feature = "trace")] +use crate::device::trace; use crate::{ binding_model::{buffer_binding_type_alignment, BindGroup, BindGroupLayout, PipelineLayout}, command::{ @@ -96,6 +98,7 @@ use crate::{ init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction}, pipeline::{self, PipelineFlags, RenderPipeline}, resource::{Resource, ResourceInfo, ResourceType}, + resource_log, track::RenderBundleScope, validation::check_buffer_usage, Label, LabelHelpers, @@ -763,6 +766,17 @@ pub struct RenderBundle { discard_hal_labels: bool, } +impl Drop for RenderBundle { + fn drop(&mut self) { + resource_log!("Destroy raw RenderBundle {:?}", self.info.label()); + + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyRenderBundle(self.info.id())); + } + } +} + #[cfg(any( not(target_arch = "wasm32"), all( diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index fed4b50a5a..26b2a0588f 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -2074,11 +2074,7 @@ impl Global { if !device.is_valid() { return Err(InvalidDevice); } - device.lock_life().triage_suspected( - &device.trackers, - #[cfg(feature = "trace")] - None, - ); + device.lock_life().triage_suspected(&device.trackers); Ok(()) } diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 1a533cfb38..3da7e0b0db 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -1,5 +1,3 @@ -#[cfg(feature = "trace")] -use crate::device::trace; use crate::{ binding_model::{BindGroup, BindGroupLayout, PipelineLayout}, command::RenderBundle, @@ -436,18 +434,16 @@ impl LifetimeTracker { } impl LifetimeTracker { - fn triage_resources( + fn triage_resources( resources_map: &mut FastHashMap>, active: &mut [ActiveSubmission], free_resources: &mut ResourceMaps, trackers: &mut impl ResourceTracker, get_resource_map: impl Fn(&mut ResourceMaps) -> &mut FastHashMap>, - mut on_remove: T, ) -> Vec> where Id: id::TypedId, R: Resource, - T: FnMut(&Id, &Arc), { let mut removed_resources = Vec::new(); resources_map.retain(|&id, resource| { @@ -459,7 +455,6 @@ impl LifetimeTracker { let is_removed = trackers.remove_abandoned(id); if is_removed { - on_remove(&id, resource); removed_resources.push(resource.clone()); get_resource_map(non_referenced_resources).insert(id, resource.clone()); } @@ -468,11 +463,7 @@ impl LifetimeTracker { removed_resources } - fn triage_suspected_render_bundles( - &mut self, - trackers: &Mutex>, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) -> &mut Self { + fn triage_suspected_render_bundles(&mut self, trackers: &Mutex>) -> &mut Self { let mut trackers = trackers.lock(); let resource_map = &mut self.suspected_resources.render_bundles; let mut removed_resources = Self::triage_resources( @@ -481,12 +472,6 @@ impl LifetimeTracker { &mut self.free_resources, &mut trackers.bundles, |maps| &mut maps.render_bundles, - |_bundle_id, _bundle| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyRenderBundle(*_bundle_id)); - } - }, ); removed_resources.drain(..).for_each(|bundle| { for v in bundle.used.buffers.write().drain_resources() { @@ -516,11 +501,7 @@ impl LifetimeTracker { self } - fn triage_suspected_bind_groups( - &mut self, - trackers: &Mutex>, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) -> &mut Self { + fn triage_suspected_bind_groups(&mut self, trackers: &Mutex>) -> &mut Self { let mut trackers = trackers.lock(); let resource_map = &mut self.suspected_resources.bind_groups; let mut removed_resource = Self::triage_resources( @@ -529,12 +510,6 @@ impl LifetimeTracker { &mut self.free_resources, &mut trackers.bind_groups, |maps| &mut maps.bind_groups, - |_bind_group_id, _bind_group| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyBindGroup(*_bind_group_id)); - } - }, ); removed_resource.drain(..).for_each(|bind_group| { for v in bind_group.used.buffers.drain_resources() { @@ -563,11 +538,7 @@ impl LifetimeTracker { self } - fn triage_suspected_texture_views( - &mut self, - trackers: &Mutex>, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) -> &mut Self { + fn triage_suspected_texture_views(&mut self, trackers: &Mutex>) -> &mut Self { let mut trackers = trackers.lock(); let resource_map = &mut self.suspected_resources.texture_views; let mut removed_resources = Self::triage_resources( @@ -576,12 +547,6 @@ impl LifetimeTracker { &mut self.free_resources, &mut trackers.views, |maps| &mut maps.texture_views, - |_texture_view_id, _texture_view| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyTextureView(*_texture_view_id)); - } - }, ); removed_resources.drain(..).for_each(|texture_view| { let mut lock = texture_view.parent.write(); @@ -594,11 +559,7 @@ impl LifetimeTracker { self } - fn triage_suspected_textures( - &mut self, - trackers: &Mutex>, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) -> &mut Self { + fn triage_suspected_textures(&mut self, trackers: &Mutex>) -> &mut Self { let mut trackers = trackers.lock(); let resource_map = &mut self.suspected_resources.textures; Self::triage_resources( @@ -607,21 +568,11 @@ impl LifetimeTracker { &mut self.free_resources, &mut trackers.textures, |maps| &mut maps.textures, - |_texture_id, _texture| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyTexture(*_texture_id)); - } - }, ); self } - fn triage_suspected_samplers( - &mut self, - trackers: &Mutex>, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) -> &mut Self { + fn triage_suspected_samplers(&mut self, trackers: &Mutex>) -> &mut Self { let mut trackers = trackers.lock(); let resource_map = &mut self.suspected_resources.samplers; Self::triage_resources( @@ -630,21 +581,11 @@ impl LifetimeTracker { &mut self.free_resources, &mut trackers.samplers, |maps| &mut maps.samplers, - |_sampler_id, _sampler| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroySampler(*_sampler_id)); - } - }, ); self } - fn triage_suspected_buffers( - &mut self, - trackers: &Mutex>, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) -> &mut Self { + fn triage_suspected_buffers(&mut self, trackers: &Mutex>) -> &mut Self { let mut trackers = trackers.lock(); let resource_map = &mut self.suspected_resources.buffers; let mut removed_resources = Self::triage_resources( @@ -653,12 +594,6 @@ impl LifetimeTracker { &mut self.free_resources, &mut trackers.buffers, |maps| &mut maps.buffers, - |_buffer_id, _buffer| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyBuffer(*_buffer_id)); - } - }, ); removed_resources.drain(..).for_each(|buffer| { if let resource::BufferMapState::Init { @@ -673,10 +608,7 @@ impl LifetimeTracker { self } - fn triage_suspected_destroyed_buffers( - &mut self, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) { + fn triage_suspected_destroyed_buffers(&mut self) { for (id, buffer) in self.suspected_resources.destroyed_buffers.drain() { let submit_index = buffer.submission_index; if let Some(resources) = self.active.iter_mut().find(|a| a.index == submit_index) { @@ -687,17 +619,10 @@ impl LifetimeTracker { } else { self.free_resources.destroyed_buffers.insert(id, buffer); } - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyBuffer(id)); - } } } - fn triage_suspected_destroyed_textures( - &mut self, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) { + fn triage_suspected_destroyed_textures(&mut self) { for (id, texture) in self.suspected_resources.destroyed_textures.drain() { let submit_index = texture.submission_index; if let Some(resources) = self.active.iter_mut().find(|a| a.index == submit_index) { @@ -708,18 +633,10 @@ impl LifetimeTracker { } else { self.free_resources.destroyed_textures.insert(id, texture); } - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyTexture(id)); - } } } - fn triage_suspected_compute_pipelines( - &mut self, - trackers: &Mutex>, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) -> &mut Self { + fn triage_suspected_compute_pipelines(&mut self, trackers: &Mutex>) -> &mut Self { let mut trackers = trackers.lock(); let resource_map = &mut self.suspected_resources.compute_pipelines; let mut removed_resources = Self::triage_resources( @@ -728,12 +645,6 @@ impl LifetimeTracker { &mut self.free_resources, &mut trackers.compute_pipelines, |maps| &mut maps.compute_pipelines, - |_compute_pipeline_id, _compute_pipeline| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyComputePipeline(*_compute_pipeline_id)); - } - }, ); removed_resources.drain(..).for_each(|compute_pipeline| { self.suspected_resources.pipeline_layouts.insert( @@ -744,11 +655,7 @@ impl LifetimeTracker { self } - fn triage_suspected_render_pipelines( - &mut self, - trackers: &Mutex>, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) -> &mut Self { + fn triage_suspected_render_pipelines(&mut self, trackers: &Mutex>) -> &mut Self { let mut trackers = trackers.lock(); let resource_map = &mut self.suspected_resources.render_pipelines; let mut removed_resources = Self::triage_resources( @@ -757,12 +664,6 @@ impl LifetimeTracker { &mut self.free_resources, &mut trackers.render_pipelines, |maps| &mut maps.render_pipelines, - |_render_pipeline_id, _render_pipeline| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyRenderPipeline(*_render_pipeline_id)); - } - }, ); removed_resources.drain(..).for_each(|render_pipeline| { self.suspected_resources.pipeline_layouts.insert( @@ -773,18 +674,11 @@ impl LifetimeTracker { self } - fn triage_suspected_pipeline_layouts( - &mut self, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) -> &mut Self { + fn triage_suspected_pipeline_layouts(&mut self) -> &mut Self { let mut removed_resources = Vec::new(); self.suspected_resources .pipeline_layouts .retain(|_pipeline_layout_id, pipeline_layout| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyPipelineLayout(*_pipeline_layout_id)); - } removed_resources.push(pipeline_layout.clone()); false }); @@ -798,20 +692,13 @@ impl LifetimeTracker { self } - fn triage_suspected_bind_group_layouts( - &mut self, - #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, - ) -> &mut Self { + fn triage_suspected_bind_group_layouts(&mut self) -> &mut Self { self.suspected_resources.bind_group_layouts.retain( |bind_group_layout_id, bind_group_layout| { //Note: this has to happen after all the suspected pipelines are destroyed //Note: nothing else can bump the refcount since the guard is locked exclusively //Note: same BGL can appear multiple times in the list, but only the last // encounter could drop the refcount to 0. - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyBindGroupLayout(*bind_group_layout_id)); - } self.free_resources .bind_group_layouts .insert(*bind_group_layout_id, bind_group_layout.clone()); @@ -830,7 +717,6 @@ impl LifetimeTracker { &mut self.free_resources, &mut trackers.query_sets, |maps| &mut maps.query_sets, - |_query_set_id, _query_set| {}, ); self } @@ -886,72 +772,24 @@ impl LifetimeTracker { /// [`self.active`]: LifetimeTracker::active /// [`triage_submissions`]: LifetimeTracker::triage_submissions /// [`self.free_resources`]: LifetimeTracker::free_resources - pub(crate) fn triage_suspected( - &mut self, - trackers: &Mutex>, - #[cfg(feature = "trace")] mut trace: Option<&mut trace::Trace>, - ) { + pub(crate) fn triage_suspected(&mut self, trackers: &Mutex>) { profiling::scope!("triage_suspected"); //NOTE: the order is important to release resources that depends between each other! - self.triage_suspected_render_bundles( - trackers, - #[cfg(feature = "trace")] - &mut trace, - ); - self.triage_suspected_compute_pipelines( - trackers, - #[cfg(feature = "trace")] - &mut trace, - ); - self.triage_suspected_render_pipelines( - trackers, - #[cfg(feature = "trace")] - &mut trace, - ); - self.triage_suspected_bind_groups( - trackers, - #[cfg(feature = "trace")] - &mut trace, - ); - self.triage_suspected_pipeline_layouts( - #[cfg(feature = "trace")] - &mut trace, - ); - self.triage_suspected_bind_group_layouts( - #[cfg(feature = "trace")] - &mut trace, - ); + self.triage_suspected_render_bundles(trackers); + self.triage_suspected_compute_pipelines(trackers); + self.triage_suspected_render_pipelines(trackers); + self.triage_suspected_bind_groups(trackers); + self.triage_suspected_pipeline_layouts(); + self.triage_suspected_bind_group_layouts(); self.triage_suspected_query_sets(trackers); - self.triage_suspected_samplers( - trackers, - #[cfg(feature = "trace")] - &mut trace, - ); + self.triage_suspected_samplers(trackers); self.triage_suspected_staging_buffers(); - self.triage_suspected_texture_views( - trackers, - #[cfg(feature = "trace")] - &mut trace, - ); - self.triage_suspected_textures( - trackers, - #[cfg(feature = "trace")] - &mut trace, - ); - self.triage_suspected_buffers( - trackers, - #[cfg(feature = "trace")] - &mut trace, - ); - self.triage_suspected_destroyed_buffers( - #[cfg(feature = "trace")] - &mut trace, - ); - self.triage_suspected_destroyed_textures( - #[cfg(feature = "trace")] - &mut trace, - ); + self.triage_suspected_texture_views(trackers); + self.triage_suspected_textures(trackers); + self.triage_suspected_buffers(trackers); + self.triage_suspected_destroyed_buffers(); + self.triage_suspected_destroyed_textures(); } /// Determine which buffers are ready to map, and which must wait for the diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index d597049709..eab6f2a093 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -334,11 +334,7 @@ impl Device { let mut life_tracker = self.lock_life(); life_tracker.suspected_resources.extend(temp_suspected); - life_tracker.triage_suspected( - &self.trackers, - #[cfg(feature = "trace")] - self.trace.lock().as_mut(), - ); + life_tracker.triage_suspected(&self.trackers); life_tracker.triage_mapped(); } diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 1d487a1bfc..6e2998235d 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -56,8 +56,8 @@ impl Drop for ShaderModule { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw ShaderModule {:?}", self.info.label()); #[cfg(feature = "trace")] - if let Some(ref mut trace) = *self.device.trace.lock() { - trace.add(trace::Action::DestroyShaderModule(self.info.id())); + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyShaderModule(self.info.id())); } unsafe { use hal::Device; @@ -251,6 +251,12 @@ impl Drop for ComputePipeline { fn drop(&mut self) { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw ComputePipeline {:?}", self.info.label()); + + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyComputePipeline(self.info.id())); + } + unsafe { use hal::Device; self.device.raw().destroy_compute_pipeline(raw); @@ -493,6 +499,12 @@ impl Drop for RenderPipeline { fn drop(&mut self) { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw RenderPipeline {:?}", self.info.label()); + + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyRenderPipeline(self.info.id())); + } + unsafe { use hal::Device; self.device.raw().destroy_render_pipeline(raw); diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 395b82517b..433c711750 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -413,7 +413,13 @@ pub struct Buffer { impl Drop for Buffer { fn drop(&mut self) { if let Some(raw) = self.raw.take() { - resource_log!("Deallocate raw Buffer (dropped) {:?}", self.info.label()); + resource_log!("Destroy raw Buffer (dropped) {:?}", self.info.label()); + + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyBuffer(self.info.id())); + } + unsafe { use hal::Device; self.device.raw().destroy_buffer(raw); @@ -639,7 +645,13 @@ impl DestroyedBuffer { impl Drop for DestroyedBuffer { fn drop(&mut self) { if let Some(raw) = self.raw.take() { - resource_log!("Deallocate raw Buffer (destroyed) {:?}", self.label()); + resource_log!("Destroy raw Buffer (destroyed) {:?}", self.label()); + + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyBuffer(self.id)); + } + unsafe { use hal::Device; self.device.raw().destroy_buffer(raw); @@ -789,6 +801,11 @@ impl Drop for Texture { }; if let Some(TextureInner::Native { raw }) = self.inner.take() { + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyTexture(self.info.id())); + } + unsafe { self.device.raw().destroy_texture(raw); } @@ -994,7 +1011,13 @@ impl DestroyedTexture { impl Drop for DestroyedTexture { fn drop(&mut self) { if let Some(raw) = self.raw.take() { - resource_log!("Deallocate raw Texture (destroyed) {:?}", self.label()); + resource_log!("Destroy raw Texture (destroyed) {:?}", self.label()); + + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyTexture(self.id)); + } + unsafe { use hal::Device; self.device.raw().destroy_texture(raw); @@ -1187,6 +1210,12 @@ impl Drop for TextureView { fn drop(&mut self) { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw TextureView {:?}", self.info.label()); + + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyTextureView(self.info.id())); + } + unsafe { use hal::Device; self.device.raw().destroy_texture_view(raw); @@ -1309,6 +1338,11 @@ impl Drop for Sampler { fn drop(&mut self) { resource_log!("Destroy raw Sampler {:?}", self.info.label()); if let Some(raw) = self.raw.take() { + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroySampler(self.info.id())); + } + unsafe { use hal::Device; self.device.raw().destroy_sampler(raw); @@ -1406,6 +1440,11 @@ impl Drop for QuerySet { fn drop(&mut self) { resource_log!("Destroy raw QuerySet {:?}", self.info.label()); if let Some(raw) = self.raw.take() { + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyQuerySet(self.info.id())); + } + unsafe { use hal::Device; self.device.raw().destroy_query_set(raw);