introduce Trackable trait

This commit is contained in:
teoxoy 2024-06-27 16:39:01 +02:00 committed by Teodor Tanasoaia
parent ae7da8f669
commit c63f0a02f2
19 changed files with 223 additions and 316 deletions

View File

@ -8,7 +8,7 @@ use crate::{
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
resource::{
DestroyedResourceError, Labeled, MissingBufferUsageError, MissingTextureUsageError,
ParentDevice, Resource, ResourceErrorIdent, ResourceInfo,
ParentDevice, Resource, ResourceErrorIdent, TrackingData,
},
resource_log,
snatch::{SnatchGuard, Snatchable},
@ -476,7 +476,7 @@ pub struct BindGroupLayout<A: HalApi> {
pub(crate) binding_count_validator: BindingTypeMaxCountValidator,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
}
impl<A: HalApi> Drop for BindGroupLayout<A> {
@ -497,12 +497,9 @@ impl<A: HalApi> Drop for BindGroupLayout<A> {
crate::impl_resource_type!(BindGroupLayout);
crate::impl_labeled!(BindGroupLayout);
crate::impl_storage_item!(BindGroupLayout);
crate::impl_trackable!(BindGroupLayout);
impl<A: HalApi> Resource for BindGroupLayout<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for BindGroupLayout<A> {}
impl<A: HalApi> ParentDevice<A> for BindGroupLayout<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -617,7 +614,7 @@ pub struct PipelineLayout<A: HalApi> {
pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
pub(crate) bind_group_layouts: ArrayVec<Arc<BindGroupLayout<A>>, { hal::MAX_BIND_GROUPS }>,
pub(crate) push_constant_ranges: ArrayVec<wgt::PushConstantRange, { SHADER_STAGE_COUNT }>,
}
@ -728,12 +725,9 @@ impl<A: HalApi> PipelineLayout<A> {
crate::impl_resource_type!(PipelineLayout);
crate::impl_labeled!(PipelineLayout);
crate::impl_storage_item!(PipelineLayout);
crate::impl_trackable!(PipelineLayout);
impl<A: HalApi> Resource for PipelineLayout<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for PipelineLayout<A> {}
impl<A: HalApi> ParentDevice<A> for PipelineLayout<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -848,7 +842,7 @@ pub struct BindGroup<A: HalApi> {
pub(crate) layout: Arc<BindGroupLayout<A>>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
pub(crate) used: BindGroupStates<A>,
pub(crate) used_buffer_ranges: Vec<BufferInitTrackerAction<A>>,
pub(crate) used_texture_ranges: Vec<TextureInitTrackerAction<A>>,
@ -944,12 +938,9 @@ impl<A: HalApi> BindGroup<A> {
crate::impl_resource_type!(BindGroup);
crate::impl_labeled!(BindGroup);
crate::impl_storage_item!(BindGroup);
crate::impl_trackable!(BindGroup);
impl<A: HalApi> Resource for BindGroup<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for BindGroup<A> {}
impl<A: HalApi> ParentDevice<A> for BindGroup<A> {
fn device(&self) -> &Arc<Device<A>> {

View File

@ -95,7 +95,7 @@ use crate::{
id,
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
pipeline::{PipelineFlags, RenderPipeline, VertexStep},
resource::{Buffer, DestroyedResourceError, Labeled, ParentDevice, Resource, ResourceInfo},
resource::{Buffer, DestroyedResourceError, Labeled, ParentDevice, Resource, TrackingData},
resource_log,
snatch::SnatchGuard,
track::RenderBundleScope,
@ -579,7 +579,7 @@ impl RenderBundleEncoder {
texture_memory_init_actions,
context: self.context,
label: desc.label.to_string(),
info: ResourceInfo::new(Some(tracker_indices)),
tracking_data: TrackingData::new(tracker_indices),
discard_hal_labels,
})
}
@ -973,7 +973,7 @@ pub struct RenderBundle<A: HalApi> {
pub(super) context: RenderPassContext,
/// The `label` from the descriptor used to create the resource.
label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
discard_hal_labels: bool,
}
@ -1186,12 +1186,9 @@ impl<A: HalApi> RenderBundle<A> {
crate::impl_resource_type!(RenderBundle);
crate::impl_labeled!(RenderBundle);
crate::impl_storage_item!(RenderBundle);
crate::impl_trackable!(RenderBundle);
impl<A: HalApi> Resource for RenderBundle<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for RenderBundle<A> {}
impl<A: HalApi> ParentDevice<A> for RenderBundle<A> {
fn device(&self) -> &Arc<Device<A>> {

View File

@ -20,7 +20,7 @@ use crate::{
pipeline::ComputePipeline,
resource::{
self, Buffer, DestroyedResourceError, Labeled, MissingBufferUsageError, ParentDevice,
Resource, ResourceErrorIdent,
Resource, ResourceErrorIdent, Trackable,
},
snatch::SnatchGuard,
track::{ResourceUsageCompatibilityError, Tracker, TrackerIndex, UsageScope},
@ -936,7 +936,7 @@ fn dispatch_indirect<A: HalApi>(
MemoryInitKind::NeedsInitializedMemory,
));
state.flush_states(Some(buffer.as_info().tracker_index()))?;
state.flush_states(Some(buffer.tracker_index()))?;
let buf_raw = buffer.try_raw(&state.snatch_guard)?;
unsafe {

View File

@ -6,7 +6,7 @@ use crate::{
device::Device,
hal_api::HalApi,
init_tracker::*,
resource::{DestroyedResourceError, Resource, Texture},
resource::{DestroyedResourceError, Resource, Texture, Trackable},
snatch::SnatchGuard,
track::{TextureTracker, Tracker},
FastHashMap,
@ -191,9 +191,7 @@ impl<A: HalApi> BakedCommands<A> {
match buffer_use.kind {
MemoryInitKind::ImplicitlyInitialized => {}
MemoryInitKind::NeedsInitializedMemory => {
match uninitialized_ranges_per_buffer
.entry(buffer_use.buffer.as_info().tracker_index())
{
match uninitialized_ranges_per_buffer.entry(buffer_use.buffer.tracker_index()) {
Entry::Vacant(e) => {
e.insert((
buffer_use.buffer.clone(),

View File

@ -36,7 +36,7 @@ use crate::lock::{rank, Mutex};
use crate::snatch::SnatchGuard;
use crate::init_tracker::BufferInitTrackerAction;
use crate::resource::{Labeled, ParentDevice, Resource, ResourceInfo};
use crate::resource::{Labeled, ParentDevice, Resource};
use crate::track::{Tracker, UsageScope};
use crate::LabelHelpers;
use crate::{api_log, global::Global, hal_api::HalApi, id, resource_log, Label};
@ -313,7 +313,6 @@ pub struct CommandBuffer<A: HalApi> {
support_clear_texture: bool,
/// The `label` from the descriptor used to create the resource.
label: String,
pub(crate) info: ResourceInfo,
/// The mutable state of this command buffer.
///
@ -352,7 +351,6 @@ impl<A: HalApi> CommandBuffer<A> {
device: device.clone(),
support_clear_texture: device.features.contains(wgt::Features::CLEAR_TEXTURE),
label: label.to_string(),
info: ResourceInfo::new(None),
data: Mutex::new(
rank::COMMAND_BUFFER_DATA,
Some(CommandBufferMutable {
@ -534,11 +532,7 @@ crate::impl_resource_type!(CommandBuffer);
crate::impl_labeled!(CommandBuffer);
crate::impl_storage_item!(CommandBuffer);
impl<A: HalApi> Resource for CommandBuffer<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for CommandBuffer<A> {}
impl<A: HalApi> ParentDevice<A> for CommandBuffer<A> {
fn device(&self) -> &Arc<Device<A>> {

View File

@ -9,7 +9,7 @@ use crate::{
hal_api::HalApi,
id,
init_tracker::MemoryInitKind,
resource::{DestroyedResourceError, ParentDevice, QuerySet},
resource::{DestroyedResourceError, ParentDevice, QuerySet, Trackable},
track::{StatelessTracker, TrackerIndex},
FastHashMap,
};
@ -33,7 +33,7 @@ impl<A: HalApi> QueryResetMap<A> {
pub fn use_query_set(&mut self, query_set: &Arc<QuerySet<A>>, query: u32) -> bool {
let vec_pair = self
.map
.entry(query_set.info.tracker_index())
.entry(query_set.tracker_index())
.or_insert_with(|| {
(
vec![false; query_set.desc.count as usize],

View File

@ -15,6 +15,7 @@ use crate::{
pipeline, present,
resource::{
self, BufferAccessError, BufferAccessResult, BufferMapOperation, CreateBufferError,
Trackable,
},
Label, LabelHelpers as _,
};
@ -354,7 +355,7 @@ impl Global {
let last_submission = {
let buffer_guard = hub.buffers.write();
match buffer_guard.get(buffer_id) {
Ok(buffer) => buffer.info.submission_index(),
Ok(buffer) => buffer.submission_index(),
Err(_) => return Ok(()),
}
};
@ -527,7 +528,7 @@ impl Global {
buffer_id,
);
let last_submit_index = buffer.info.submission_index();
let last_submit_index = buffer.submission_index();
let device = buffer.device.clone();
@ -544,7 +545,7 @@ impl Global {
.lock_life()
.suspected_resources
.buffers
.insert(buffer.info.tracker_index(), buffer);
.insert(buffer.tracker_index(), buffer);
}
if wait {
@ -762,7 +763,7 @@ impl Global {
t.add(trace::Action::DestroyTexture(texture_id));
}
let last_submit_index = texture.info.submission_index();
let last_submit_index = texture.submission_index();
let device = &texture.device;
{
@ -782,7 +783,7 @@ impl Global {
.lock_life()
.suspected_resources
.textures
.insert(texture.info.tracker_index(), texture.clone());
.insert(texture.tracker_index(), texture.clone());
}
}
@ -878,13 +879,13 @@ impl Global {
t.add(trace::Action::DestroyTextureView(texture_view_id));
}
let last_submit_index = view.info.submission_index();
let last_submit_index = view.submission_index();
view.device
.lock_life()
.suspected_resources
.texture_views
.insert(view.info.tracker_index(), view.clone());
.insert(view.tracker_index(), view.clone());
if wait {
match view.device.wait_for_submit(last_submit_index) {
@ -957,7 +958,7 @@ impl Global {
.lock_life()
.suspected_resources
.samplers
.insert(sampler.info.tracker_index(), sampler.clone());
.insert(sampler.tracker_index(), sampler.clone());
}
}
@ -1063,7 +1064,7 @@ impl Global {
.lock_life()
.suspected_resources
.bind_group_layouts
.insert(layout.info.tracker_index(), layout.clone());
.insert(layout.tracker_index(), layout.clone());
}
}
@ -1126,7 +1127,7 @@ impl Global {
.lock_life()
.suspected_resources
.pipeline_layouts
.insert(layout.info.tracker_index(), layout.clone());
.insert(layout.tracker_index(), layout.clone());
}
}
@ -1213,7 +1214,7 @@ impl Global {
.lock_life()
.suspected_resources
.bind_groups
.insert(bind_group.info.tracker_index(), bind_group.clone());
.insert(bind_group.tracker_index(), bind_group.clone());
}
}
@ -1522,7 +1523,7 @@ impl Global {
.lock_life()
.suspected_resources
.render_bundles
.insert(bundle.info.tracker_index(), bundle.clone());
.insert(bundle.tracker_index(), bundle.clone());
}
}
@ -1585,7 +1586,7 @@ impl Global {
.lock_life()
.suspected_resources
.query_sets
.insert(query_set.info.tracker_index(), query_set.clone());
.insert(query_set.tracker_index(), query_set.clone());
}
}
@ -1724,12 +1725,12 @@ impl Global {
life_lock
.suspected_resources
.render_pipelines
.insert(pipeline.info.tracker_index(), pipeline.clone());
.insert(pipeline.tracker_index(), pipeline.clone());
life_lock.suspected_resources.pipeline_layouts.insert(
pipeline.layout.info.tracker_index(),
pipeline.layout.clone(),
);
life_lock
.suspected_resources
.pipeline_layouts
.insert(pipeline.layout.tracker_index(), pipeline.layout.clone());
}
}
@ -1861,11 +1862,11 @@ impl Global {
life_lock
.suspected_resources
.compute_pipelines
.insert(pipeline.info.tracker_index(), pipeline.clone());
life_lock.suspected_resources.pipeline_layouts.insert(
pipeline.layout.info.tracker_index(),
pipeline.layout.clone(),
);
.insert(pipeline.tracker_index(), pipeline.clone());
life_lock
.suspected_resources
.pipeline_layouts
.insert(pipeline.layout.tracker_index(), pipeline.layout.clone());
}
}

View File

@ -10,8 +10,8 @@ use crate::{
lock::Mutex,
pipeline::{ComputePipeline, RenderPipeline},
resource::{
self, Buffer, DestroyedBuffer, DestroyedTexture, Labeled, QuerySet, Resource, Sampler,
StagingBuffer, Texture, TextureView,
self, Buffer, DestroyedBuffer, DestroyedTexture, Labeled, QuerySet, Sampler, StagingBuffer,
Texture, TextureView, Trackable,
},
snatch::SnatchGuard,
track::{ResourceTracker, Tracker, TrackerIndex},
@ -314,14 +314,12 @@ impl<A: HalApi> LifetimeTracker<A> {
for res in temp_resources {
match res {
TempResource::Buffer(raw) => {
last_resources
.buffers
.insert(raw.as_info().tracker_index(), raw);
last_resources.buffers.insert(raw.tracker_index(), raw);
}
TempResource::StagingBuffer(raw) => {
last_resources
.staging_buffers
.insert(raw.as_info().tracker_index(), raw);
.insert(raw.tracker_index(), raw);
}
TempResource::DestroyedBuffer(destroyed) => {
last_resources
@ -329,9 +327,7 @@ impl<A: HalApi> LifetimeTracker<A> {
.insert(destroyed.tracker_index, destroyed);
}
TempResource::Texture(raw) => {
last_resources
.textures
.insert(raw.as_info().tracker_index(), raw);
last_resources.textures.insert(raw.tracker_index(), raw);
}
TempResource::DestroyedTexture(destroyed) => {
last_resources
@ -354,12 +350,12 @@ impl<A: HalApi> LifetimeTracker<A> {
for v in self.future_suspected_buffers.drain(..) {
self.suspected_resources
.buffers
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
for v in self.future_suspected_textures.drain(..) {
self.suspected_resources
.textures
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
}
@ -427,12 +423,10 @@ impl<A: HalApi> LifetimeTracker<A> {
if let Some(resources) = resources {
match temp_resource {
TempResource::Buffer(raw) => {
resources.buffers.insert(raw.as_info().tracker_index(), raw);
resources.buffers.insert(raw.tracker_index(), raw);
}
TempResource::StagingBuffer(raw) => {
resources
.staging_buffers
.insert(raw.as_info().tracker_index(), raw);
resources.staging_buffers.insert(raw.tracker_index(), raw);
}
TempResource::DestroyedBuffer(destroyed) => {
resources
@ -440,9 +434,7 @@ impl<A: HalApi> LifetimeTracker<A> {
.insert(destroyed.tracker_index, destroyed);
}
TempResource::Texture(raw) => {
resources
.textures
.insert(raw.as_info().tracker_index(), raw);
resources.textures.insert(raw.tracker_index(), raw);
}
TempResource::DestroyedTexture(destroyed) => {
resources
@ -489,7 +481,7 @@ impl<A: HalApi> LifetimeTracker<A> {
get_resource_map: impl Fn(&mut ResourceMaps<A>) -> &mut FastHashMap<TrackerIndex, Arc<R>>,
) -> Vec<Arc<R>>
where
R: Resource,
R: Trackable,
{
let mut removed_resources = Vec::new();
suspected_resources.retain(|&index, resource| {
@ -499,7 +491,7 @@ impl<A: HalApi> LifetimeTracker<A> {
// If this resource is used by commands in flight, save
// it in that submission's `last_resources` list.
let submit_index = resource.as_info().submission_index();
let submit_index = resource.submission_index();
let last_resources = active
.iter_mut()
.find(|a| a.index == submit_index)
@ -527,27 +519,27 @@ impl<A: HalApi> LifetimeTracker<A> {
for v in bundle.used.buffers.write().drain_resources() {
self.suspected_resources
.buffers
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
for v in bundle.used.textures.write().drain_resources() {
self.suspected_resources
.textures
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
for v in bundle.used.bind_groups.write().drain_resources() {
self.suspected_resources
.bind_groups
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
for v in bundle.used.render_pipelines.write().drain_resources() {
self.suspected_resources
.render_pipelines
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
for v in bundle.used.query_sets.write().drain_resources() {
self.suspected_resources
.query_sets
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
}
self
@ -566,28 +558,27 @@ impl<A: HalApi> LifetimeTracker<A> {
for v in bind_group.used.buffers.drain_resources() {
self.suspected_resources
.buffers
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
for v in bind_group.used.textures.drain_resources() {
self.suspected_resources
.textures
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
for v in bind_group.used.views.drain_resources() {
self.suspected_resources
.texture_views
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
for v in bind_group.used.samplers.drain_resources() {
self.suspected_resources
.samplers
.insert(v.as_info().tracker_index(), v);
.insert(v.tracker_index(), v);
}
self.suspected_resources.bind_group_layouts.insert(
bind_group.layout.as_info().tracker_index(),
bind_group.layout.clone(),
);
self.suspected_resources
.bind_group_layouts
.insert(bind_group.layout.tracker_index(), bind_group.layout.clone());
}
self
}
@ -681,7 +672,7 @@ impl<A: HalApi> LifetimeTracker<A> {
);
for compute_pipeline in removed_resources {
self.suspected_resources.pipeline_layouts.insert(
compute_pipeline.layout.as_info().tracker_index(),
compute_pipeline.layout.tracker_index(),
compute_pipeline.layout.clone(),
);
}
@ -699,7 +690,7 @@ impl<A: HalApi> LifetimeTracker<A> {
);
for render_pipeline in removed_resources {
self.suspected_resources.pipeline_layouts.insert(
render_pipeline.layout.as_info().tracker_index(),
render_pipeline.layout.tracker_index(),
render_pipeline.layout.clone(),
);
}
@ -718,7 +709,7 @@ impl<A: HalApi> LifetimeTracker<A> {
for bgl in &pipeline_layout.bind_group_layouts {
self.suspected_resources
.bind_group_layouts
.insert(bgl.as_info().tracker_index(), bgl.clone());
.insert(bgl.tracker_index(), bgl.clone());
}
});
self
@ -813,7 +804,7 @@ impl<A: HalApi> LifetimeTracker<A> {
}
for buffer in self.mapped.drain(..) {
let submit_index = buffer.info.submission_index();
let submit_index = buffer.submission_index();
log::trace!(
"Mapping of {} at submission {:?} gets assigned to active {:?}",
buffer.error_ident(),
@ -848,7 +839,7 @@ impl<A: HalApi> LifetimeTracker<A> {
Vec::with_capacity(self.ready_to_map.len());
for buffer in self.ready_to_map.drain(..) {
let tracker_index = buffer.info.tracker_index();
let tracker_index = buffer.tracker_index();
let is_removed = {
let mut trackers = trackers.lock();
trackers.buffers.remove_abandoned(tracker_index)

View File

@ -17,8 +17,8 @@ use crate::{
lock::{rank, Mutex, RwLockWriteGuard},
resource::{
Buffer, BufferAccessError, BufferMapState, DestroyedBuffer, DestroyedResourceError,
DestroyedTexture, Labeled, ParentDevice, Resource, ResourceErrorIdent, ResourceInfo,
StagingBuffer, Texture, TextureInner,
DestroyedTexture, Labeled, ParentDevice, Resource, ResourceErrorIdent, StagingBuffer,
Texture, TextureInner, Trackable, TrackingData,
},
resource_log,
track::{self, TrackerIndex},
@ -39,7 +39,6 @@ use super::Device;
pub struct Queue<A: HalApi> {
pub(crate) device: Option<Arc<Device<A>>>,
pub(crate) raw: Option<A::Queue>,
pub(crate) info: ResourceInfo,
}
crate::impl_resource_type!(Queue);
@ -51,11 +50,7 @@ impl<A: HalApi> Labeled for Queue<A> {
}
crate::impl_storage_item!(Queue);
impl<A: HalApi> Resource for Queue<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for Queue<A> {}
impl<A: HalApi> ParentDevice<A> for Queue<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -250,21 +245,20 @@ impl<A: HalApi> PendingWrites<A> {
pub fn insert_buffer(&mut self, buffer: &Arc<Buffer<A>>) {
self.dst_buffers
.insert(buffer.info.tracker_index(), buffer.clone());
.insert(buffer.tracker_index(), buffer.clone());
}
pub fn insert_texture(&mut self, texture: &Arc<Texture<A>>) {
self.dst_textures
.insert(texture.info.tracker_index(), texture.clone());
.insert(texture.tracker_index(), texture.clone());
}
pub fn contains_buffer(&self, buffer: &Arc<Buffer<A>>) -> bool {
self.dst_buffers.contains_key(&buffer.info.tracker_index())
self.dst_buffers.contains_key(&buffer.tracker_index())
}
pub fn contains_texture(&self, texture: &Arc<Texture<A>>) -> bool {
self.dst_textures
.contains_key(&texture.info.tracker_index())
self.dst_textures.contains_key(&texture.tracker_index())
}
pub fn consume_temp(&mut self, resource: TempResource<A>) {
@ -350,7 +344,7 @@ fn prepare_staging_buffer<A: HalApi>(
raw: Mutex::new(rank::STAGING_BUFFER_RAW, Some(buffer)),
device: device.clone(),
size,
info: ResourceInfo::new(Some(device.tracker_indices.staging_buffers.clone())),
tracking_data: TrackingData::new(device.tracker_indices.staging_buffers.clone()),
is_coherent: mapping.is_coherent,
};
@ -646,8 +640,7 @@ impl Global {
let src_buffer_size = staging_buffer.size;
self.queue_validate_write_buffer_impl(&dst, buffer_id, buffer_offset, src_buffer_size)?;
dst.info
.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1);
dst.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1);
let region = wgt::BufferSize::new(src_buffer_size).map(|size| hal::BufferCopy {
src_offset: 0,
@ -847,8 +840,7 @@ impl Global {
// call above. Since we've held `texture_guard` the whole time, we know
// the texture hasn't gone away in the mean time, so we can unwrap.
let dst = hub.textures.get(destination.texture).unwrap();
dst.info
.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1);
dst.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1);
let dst_raw = dst.try_raw(&snatch_guard)?;
@ -1104,8 +1096,7 @@ impl Global {
.drain(init_layer_range);
}
}
dst.info
.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1);
dst.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1);
let snatch_guard = device.snatchable_lock.read();
let dst_raw = dst.try_raw(&snatch_guard)?;
@ -1234,7 +1225,7 @@ impl Global {
profiling::scope!("buffers");
for buffer in cmd_buf_trackers.buffers.used_resources() {
buffer.check_destroyed(&snatch_guard)?;
buffer.info.use_at(submit_index);
buffer.use_at(submit_index);
match *buffer.map_state.lock() {
BufferMapState::Idle => (),
@ -1261,7 +1252,7 @@ impl Global {
true
}
};
texture.info.use_at(submit_index);
texture.use_at(submit_index);
if should_extend {
unsafe {
used_surface_textures
@ -1278,21 +1269,21 @@ impl Global {
{
profiling::scope!("views");
for texture_view in cmd_buf_trackers.views.used_resources() {
texture_view.info.use_at(submit_index);
texture_view.use_at(submit_index);
}
}
{
profiling::scope!("bind groups (+ referenced views/samplers)");
for bg in cmd_buf_trackers.bind_groups.used_resources() {
bg.info.use_at(submit_index);
bg.use_at(submit_index);
// We need to update the submission indices for the contained
// state-less (!) resources as well, so that they don't get
// deleted too early if the parent bind group goes out of scope.
for view in bg.used.views.used_resources() {
view.info.use_at(submit_index);
view.use_at(submit_index);
}
for sampler in bg.used.samplers.used_resources() {
sampler.info.use_at(submit_index);
sampler.use_at(submit_index);
}
}
}
@ -1301,7 +1292,7 @@ impl Global {
for compute_pipeline in
cmd_buf_trackers.compute_pipelines.used_resources()
{
compute_pipeline.info.use_at(submit_index);
compute_pipeline.use_at(submit_index);
}
}
{
@ -1309,13 +1300,13 @@ impl Global {
for render_pipeline in
cmd_buf_trackers.render_pipelines.used_resources()
{
render_pipeline.info.use_at(submit_index);
render_pipeline.use_at(submit_index);
}
}
{
profiling::scope!("query sets");
for query_set in cmd_buf_trackers.query_sets.used_resources() {
query_set.info.use_at(submit_index);
query_set.use_at(submit_index);
}
}
{
@ -1323,18 +1314,18 @@ impl Global {
"render bundles (+ referenced pipelines/query sets)"
);
for bundle in cmd_buf_trackers.bundles.used_resources() {
bundle.info.use_at(submit_index);
bundle.use_at(submit_index);
// We need to update the submission indices for the contained
// state-less (!) resources as well, excluding the bind groups.
// They don't get deleted too early if the bundle goes out of scope.
for render_pipeline in
bundle.used.render_pipelines.read().used_resources()
{
render_pipeline.info.use_at(submit_index);
render_pipeline.use_at(submit_index);
}
for query_set in bundle.used.query_sets.read().used_resources()
{
query_set.info.use_at(submit_index);
query_set.use_at(submit_index);
}
}
}

View File

@ -24,8 +24,8 @@ use crate::{
pool::ResourcePool,
registry::Registry,
resource::{
self, Buffer, Labeled, ParentDevice, QuerySet, Resource, ResourceInfo, Sampler, Texture,
TextureView, TextureViewNotRenderableReason,
self, Buffer, Labeled, ParentDevice, QuerySet, Resource, Sampler, Texture, TextureView,
TextureViewNotRenderableReason, Trackable, TrackingData,
},
resource_log,
snatch::{SnatchGuard, SnatchLock, Snatchable},
@ -96,7 +96,6 @@ pub struct Device<A: HalApi> {
pub(crate) zero_buffer: Option<A::Buffer>,
/// The `label` from the descriptor used to create the resource.
label: String,
pub(crate) info: ResourceInfo,
pub(crate) command_allocator: command::CommandAllocator<A>,
//Note: The submission index here corresponds to the last submission that is done.
@ -271,7 +270,6 @@ impl<A: HalApi> Device<A> {
queue_to_drop: OnceCell::new(),
zero_buffer: Some(zero_buffer),
label: desc.label.to_string(),
info: ResourceInfo::new(None),
command_allocator,
active_submission_index: AtomicU64::new(0),
fence: RwLock::new(rank::DEVICE_FENCE, Some(fence)),
@ -502,56 +500,56 @@ impl<A: HalApi> Device<A> {
if resource.is_unique() {
temp_suspected
.buffers
.insert(resource.as_info().tracker_index(), resource.clone());
.insert(resource.tracker_index(), resource.clone());
}
}
for resource in trackers.textures.used_resources() {
if resource.is_unique() {
temp_suspected
.textures
.insert(resource.as_info().tracker_index(), resource.clone());
.insert(resource.tracker_index(), resource.clone());
}
}
for resource in trackers.views.used_resources() {
if resource.is_unique() {
temp_suspected
.texture_views
.insert(resource.as_info().tracker_index(), resource.clone());
.insert(resource.tracker_index(), resource.clone());
}
}
for resource in trackers.bind_groups.used_resources() {
if resource.is_unique() {
temp_suspected
.bind_groups
.insert(resource.as_info().tracker_index(), resource.clone());
.insert(resource.tracker_index(), resource.clone());
}
}
for resource in trackers.samplers.used_resources() {
if resource.is_unique() {
temp_suspected
.samplers
.insert(resource.as_info().tracker_index(), resource.clone());
.insert(resource.tracker_index(), resource.clone());
}
}
for resource in trackers.compute_pipelines.used_resources() {
if resource.is_unique() {
temp_suspected
.compute_pipelines
.insert(resource.as_info().tracker_index(), resource.clone());
.insert(resource.tracker_index(), resource.clone());
}
}
for resource in trackers.render_pipelines.used_resources() {
if resource.is_unique() {
temp_suspected
.render_pipelines
.insert(resource.as_info().tracker_index(), resource.clone());
.insert(resource.tracker_index(), resource.clone());
}
}
for resource in trackers.query_sets.used_resources() {
if resource.is_unique() {
temp_suspected
.query_sets
.insert(resource.as_info().tracker_index(), resource.clone());
.insert(resource.tracker_index(), resource.clone());
}
}
}
@ -660,7 +658,7 @@ impl<A: HalApi> Device<A> {
sync_mapped_writes: Mutex::new(rank::BUFFER_SYNC_MAPPED_WRITES, None),
map_state: Mutex::new(rank::BUFFER_MAP_STATE, resource::BufferMapState::Idle),
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.buffers.clone())),
tracking_data: TrackingData::new(self.tracker_indices.buffers.clone()),
bind_groups: Mutex::new(rank::BUFFER_BIND_GROUPS, Vec::new()),
})
}
@ -688,7 +686,7 @@ impl<A: HalApi> Device<A> {
layers: 0..desc.array_layer_count(),
},
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.textures.clone())),
tracking_data: TrackingData::new(self.tracker_indices.textures.clone()),
clear_mode: RwLock::new(rank::TEXTURE_CLEAR_MODE, clear_mode),
views: Mutex::new(rank::TEXTURE_VIEWS, Vec::new()),
bind_groups: Mutex::new(rank::TEXTURE_BIND_GROUPS, Vec::new()),
@ -712,7 +710,7 @@ impl<A: HalApi> Device<A> {
sync_mapped_writes: Mutex::new(rank::BUFFER_SYNC_MAPPED_WRITES, None),
map_state: Mutex::new(rank::BUFFER_MAP_STATE, resource::BufferMapState::Idle),
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.buffers.clone())),
tracking_data: TrackingData::new(self.tracker_indices.buffers.clone()),
bind_groups: Mutex::new(rank::BUFFER_BIND_GROUPS, Vec::new()),
}
}
@ -1289,7 +1287,7 @@ impl<A: HalApi> Device<A> {
samples: texture.desc.sample_count,
selector,
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.texture_views.clone())),
tracking_data: TrackingData::new(self.tracker_indices.texture_views.clone()),
})
}
@ -1396,7 +1394,7 @@ impl<A: HalApi> Device<A> {
raw: Some(raw),
device: self.clone(),
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.samplers.clone())),
tracking_data: TrackingData::new(self.tracker_indices.samplers.clone()),
comparison: desc.compare.is_some(),
filtering: desc.min_filter == wgt::FilterMode::Linear
|| desc.mag_filter == wgt::FilterMode::Linear,
@ -1530,7 +1528,6 @@ impl<A: HalApi> Device<A> {
device: self.clone(),
interface: Some(interface),
label: desc.label.to_string(),
info: ResourceInfo::new(None),
})
}
@ -1573,7 +1570,6 @@ impl<A: HalApi> Device<A> {
device: self.clone(),
interface: None,
label: desc.label.to_string(),
info: ResourceInfo::new(None),
})
}
@ -1846,7 +1842,7 @@ impl<A: HalApi> Device<A> {
origin,
binding_count_validator: count_validator,
label: label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.bind_group_layouts.clone())),
tracking_data: TrackingData::new(self.tracker_indices.bind_group_layouts.clone()),
})
}
@ -2276,7 +2272,7 @@ impl<A: HalApi> Device<A> {
device: self.clone(),
layout: layout.clone(),
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.bind_groups.clone())),
tracking_data: TrackingData::new(self.tracker_indices.bind_groups.clone()),
used,
used_buffer_ranges,
used_texture_ranges,
@ -2559,7 +2555,7 @@ impl<A: HalApi> Device<A> {
raw: Some(raw),
device: self.clone(),
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.pipeline_layouts.clone())),
tracking_data: TrackingData::new(self.tracker_indices.pipeline_layouts.clone()),
bind_group_layouts,
push_constant_ranges: desc.push_constant_ranges.iter().cloned().collect(),
})
@ -2746,7 +2742,7 @@ impl<A: HalApi> Device<A> {
_shader_module: shader_module,
late_sized_buffer_groups,
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.compute_pipelines.clone())),
tracking_data: TrackingData::new(self.tracker_indices.compute_pipelines.clone()),
};
Ok(pipeline)
}
@ -3398,7 +3394,7 @@ impl<A: HalApi> Device<A> {
vertex_steps,
late_sized_buffer_groups,
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.render_pipelines.clone())),
tracking_data: TrackingData::new(self.tracker_indices.render_pipelines.clone()),
};
Ok(pipeline)
}
@ -3444,7 +3440,7 @@ impl<A: HalApi> Device<A> {
let cache = pipeline::PipelineCache {
device: self.clone(),
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.pipeline_caches.clone())),
tracking_data: TrackingData::new(self.tracker_indices.pipeline_caches.clone()),
// This would be none in the error condition, which we don't implement yet
raw: Some(raw),
};
@ -3561,7 +3557,7 @@ impl<A: HalApi> Device<A> {
raw: Some(unsafe { self.raw().create_query_set(&hal_desc).unwrap() }),
device: self.clone(),
label: desc.label.to_string(),
info: ResourceInfo::new(Some(self.tracker_indices.query_sets.clone())),
tracking_data: TrackingData::new(self.tracker_indices.query_sets.clone()),
desc: desc.map_label(|_| ()),
})
}
@ -3673,8 +3669,4 @@ crate::impl_resource_type!(Device);
crate::impl_labeled!(Device);
crate::impl_storage_item!(Device);
impl<A: HalApi> Resource for Device<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for Device<A> {}

View File

@ -9,7 +9,7 @@ use crate::{
id::{markers, AdapterId, DeviceId, Id, Marker, QueueId, SurfaceId},
lock::{rank, Mutex},
present::Presentation,
resource::{Labeled, Resource, ResourceInfo, ResourceType},
resource::{Labeled, Resource, ResourceType},
resource_log, LabelHelpers, DOWNLEVEL_WARNING_MESSAGE,
};
@ -133,7 +133,6 @@ impl Instance {
pub struct Surface {
pub(crate) presentation: Mutex<Option<Presentation>>,
pub(crate) info: ResourceInfo,
#[cfg(vulkan)]
pub vulkan: Option<HalSurface<hal::api::Vulkan>>,
@ -158,11 +157,7 @@ impl crate::storage::StorageItem for Surface {
type Marker = markers::Surface;
}
impl Resource for Surface {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl Resource for Surface {}
impl Surface {
pub fn get_capabilities<A: HalApi>(
@ -185,7 +180,6 @@ impl Surface {
pub struct Adapter<A: HalApi> {
pub(crate) raw: hal::ExposedAdapter<A>,
pub(crate) info: ResourceInfo,
}
impl<A: HalApi> Adapter<A> {
@ -202,10 +196,7 @@ impl<A: HalApi> Adapter<A> {
.min_storage_buffer_offset_alignment
.max(MIN_BUFFER_OFFSET_ALIGNMENT_LOWER_BOUND);
Self {
raw,
info: ResourceInfo::new(None),
}
Self { raw }
}
pub fn is_surface_supported(&self, surface: &Surface) -> bool {
@ -309,7 +300,6 @@ impl<A: HalApi> Adapter<A> {
let queue = Queue {
device: None,
raw: Some(hal_device.queue),
info: ResourceInfo::new(None),
};
return Ok((device, queue));
}
@ -386,11 +376,7 @@ impl<A: HalApi> Labeled for Adapter<A> {
}
crate::impl_storage_item!(Adapter);
impl<A: HalApi> Resource for Adapter<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for Adapter<A> {}
#[derive(Clone, Debug, Error)]
#[non_exhaustive]
@ -533,7 +519,6 @@ impl Global {
let surface = Surface {
presentation: Mutex::new(rank::SURFACE_PRESENTATION, None),
info: ResourceInfo::new(None),
#[cfg(vulkan)]
vulkan: init::<hal::api::Vulkan>(
@ -597,7 +582,6 @@ impl Global {
let surface = Surface {
presentation: Mutex::new(rank::SURFACE_PRESENTATION, None),
info: ResourceInfo::new(None),
metal: Some(self.instance.metal.as_ref().map_or(
Err(CreateSurfaceError::BackendNotEnabled(Backend::Metal)),
|inst| {
@ -626,7 +610,6 @@ impl Global {
) -> Result<SurfaceId, CreateSurfaceError> {
let surface = Surface {
presentation: Mutex::new(rank::SURFACE_PRESENTATION, None),
info: ResourceInfo::new(None),
dx12: Some(create_surface_func(
self.instance
.dx12

View File

@ -5,7 +5,7 @@ use crate::{
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures, RenderPassContext},
hal_api::HalApi,
id::{PipelineCacheId, PipelineLayoutId, ShaderModuleId},
resource::{Labeled, ParentDevice, Resource, ResourceInfo},
resource::{Labeled, ParentDevice, Resource, TrackingData},
resource_log, validation, Label,
};
use arrayvec::ArrayVec;
@ -52,7 +52,6 @@ pub struct ShaderModule<A: HalApi> {
pub(crate) interface: Option<validation::Interface>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
}
impl<A: HalApi> Drop for ShaderModule<A> {
@ -71,11 +70,7 @@ crate::impl_resource_type!(ShaderModule);
crate::impl_labeled!(ShaderModule);
crate::impl_storage_item!(ShaderModule);
impl<A: HalApi> Resource for ShaderModule<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for ShaderModule<A> {}
impl<A: HalApi> ParentDevice<A> for ShaderModule<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -218,7 +213,7 @@ pub struct ComputePipeline<A: HalApi> {
pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
}
impl<A: HalApi> Drop for ComputePipeline<A> {
@ -236,12 +231,9 @@ impl<A: HalApi> Drop for ComputePipeline<A> {
crate::impl_resource_type!(ComputePipeline);
crate::impl_labeled!(ComputePipeline);
crate::impl_storage_item!(ComputePipeline);
crate::impl_trackable!(ComputePipeline);
impl<A: HalApi> Resource for ComputePipeline<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for ComputePipeline<A> {}
impl<A: HalApi> ParentDevice<A> for ComputePipeline<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -284,7 +276,7 @@ pub struct PipelineCache<A: HalApi> {
pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
}
impl<A: HalApi> Drop for PipelineCache<A> {
@ -302,12 +294,9 @@ impl<A: HalApi> Drop for PipelineCache<A> {
crate::impl_resource_type!(PipelineCache);
crate::impl_labeled!(PipelineCache);
crate::impl_storage_item!(PipelineCache);
crate::impl_trackable!(PipelineCache);
impl<A: HalApi> Resource for PipelineCache<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for PipelineCache<A> {}
impl<A: HalApi> ParentDevice<A> for PipelineCache<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -541,7 +530,7 @@ pub struct RenderPipeline<A: HalApi> {
pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
}
impl<A: HalApi> Drop for RenderPipeline<A> {
@ -559,12 +548,9 @@ impl<A: HalApi> Drop for RenderPipeline<A> {
crate::impl_resource_type!(RenderPipeline);
crate::impl_labeled!(RenderPipeline);
crate::impl_storage_item!(RenderPipeline);
crate::impl_trackable!(RenderPipeline);
impl<A: HalApi> Resource for RenderPipeline<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for RenderPipeline<A> {}
impl<A: HalApi> ParentDevice<A> for RenderPipeline<A> {
fn device(&self) -> &Arc<Device<A>> {

View File

@ -22,7 +22,7 @@ use crate::{
hal_label, id,
init_tracker::TextureInitTracker,
lock::{rank, Mutex, RwLock},
resource::{self, ResourceInfo},
resource::{self, Trackable, TrackingData},
snatch::Snatchable,
track,
};
@ -225,7 +225,7 @@ impl Global {
mips: 0..1,
},
label: String::from("<Surface Texture>"),
info: ResourceInfo::new(Some(device.tracker_indices.textures.clone())),
tracking_data: TrackingData::new(device.tracker_indices.textures.clone()),
clear_mode: RwLock::new(
rank::TEXTURE_CLEAR_MODE,
resource::TextureClearMode::Surface {
@ -326,7 +326,7 @@ impl Global {
.trackers
.lock()
.textures
.remove(texture.info.tracker_index());
.remove(texture.tracker_index());
let mut exclusive_snatch_guard = device.snatchable_lock.write();
let suf = A::surface_as_hal(&surface);
let mut inner = texture.inner_mut(&mut exclusive_snatch_guard);
@ -420,7 +420,7 @@ impl Global {
.trackers
.lock()
.textures
.remove(texture.info.tracker_index());
.remove(texture.tracker_index());
let suf = A::surface_as_hal(&surface);
let exclusive_snatch_guard = device.snatchable_lock.write();
match texture.inner.snatch(exclusive_snatch_guard).unwrap() {

View File

@ -202,14 +202,12 @@ mod tests {
use crate::{
id::Marker,
resource::{Labeled, Resource, ResourceInfo, ResourceType},
resource::{Labeled, ResourceType},
storage::StorageItem,
};
use super::Registry;
struct TestData {
info: ResourceInfo,
}
struct TestData;
struct TestDataId;
impl Marker for TestDataId {}
@ -226,12 +224,6 @@ mod tests {
type Marker = TestDataId;
}
impl Resource for TestData {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
#[test]
fn simultaneous_registration() {
let registry = Registry::without_backend();
@ -239,9 +231,7 @@ mod tests {
for _ in 0..5 {
s.spawn(|| {
for _ in 0..1000 {
let value = Arc::new(TestData {
info: ResourceInfo::new(None),
});
let value = Arc::new(TestData);
let new_id = registry.prepare(None);
let (id, _) = new_id.assign(value);
registry.unregister(id);

View File

@ -54,9 +54,9 @@ use std::{
/// [`Device`]: crate::device::resource::Device
/// [`Buffer`]: crate::resource::Buffer
#[derive(Debug)]
pub(crate) struct ResourceInfo {
pub(crate) struct TrackingData {
tracker_index: TrackerIndex,
tracker_indices: Option<Arc<SharedTrackerIndexAllocator>>,
tracker_indices: Arc<SharedTrackerIndexAllocator>,
/// The index of the last queue submission in which the resource
/// was used.
///
@ -67,29 +67,22 @@ pub(crate) struct ResourceInfo {
submission_index: AtomicUsize,
}
impl Drop for ResourceInfo {
impl Drop for TrackingData {
fn drop(&mut self) {
if let Some(indices) = &self.tracker_indices {
indices.free(self.tracker_index);
}
self.tracker_indices.free(self.tracker_index);
}
}
impl ResourceInfo {
pub(crate) fn new(tracker_indices: Option<Arc<SharedTrackerIndexAllocator>>) -> Self {
let tracker_index = tracker_indices
.as_ref()
.map(|indices| indices.alloc())
.unwrap_or(TrackerIndex::INVALID);
impl TrackingData {
pub(crate) fn new(tracker_indices: Arc<SharedTrackerIndexAllocator>) -> Self {
Self {
tracker_index,
tracker_index: tracker_indices.alloc(),
tracker_indices,
submission_index: AtomicUsize::new(0),
}
}
pub(crate) fn tracker_index(&self) -> TrackerIndex {
debug_assert!(self.tracker_index != TrackerIndex::INVALID);
self.tracker_index
}
@ -187,9 +180,32 @@ macro_rules! impl_labeled {
};
}
pub(crate) trait Resource: 'static + Sized + WasmNotSendSync + Labeled {
fn as_info(&self) -> &ResourceInfo;
pub(crate) trait Trackable: Labeled {
fn tracker_index(&self) -> TrackerIndex;
/// Record that this resource will be used by the queue submission with the
/// given index.
fn use_at(&self, submit_index: SubmissionIndex);
fn submission_index(&self) -> SubmissionIndex;
}
#[macro_export]
macro_rules! impl_trackable {
($ty:ident) => {
impl<A: HalApi> $crate::resource::Trackable for $ty<A> {
fn tracker_index(&self) -> $crate::track::TrackerIndex {
self.tracking_data.tracker_index()
}
fn use_at(&self, submit_index: $crate::SubmissionIndex) {
self.tracking_data.use_at(submit_index)
}
fn submission_index(&self) -> $crate::SubmissionIndex {
self.tracking_data.submission_index()
}
}
};
}
pub(crate) trait Resource: 'static + Sized + WasmNotSendSync + Labeled {
fn ref_count(self: &Arc<Self>) -> usize {
Arc::strong_count(self)
}
@ -448,7 +464,7 @@ pub struct Buffer<A: HalApi> {
pub(crate) sync_mapped_writes: Mutex<Option<hal::MemoryRange>>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
pub(crate) map_state: Mutex<BufferMapState<A>>,
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
}
@ -661,8 +677,7 @@ impl<A: HalApi> Buffer<A> {
}
}
self.info
.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1);
self.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1);
let region = wgt::BufferSize::new(self.size).map(|size| hal::BufferCopy {
src_offset: 0,
dst_offset: 0,
@ -748,8 +763,8 @@ impl<A: HalApi> Buffer<A> {
queue::TempResource::DestroyedBuffer(Arc::new(DestroyedBuffer {
raw: Some(raw),
device: Arc::clone(&self.device),
submission_index: self.info.submission_index(),
tracker_index: self.info.tracker_index(),
submission_index: self.submission_index(),
tracker_index: self.tracker_index(),
label: self.label().to_owned(),
bind_groups,
}))
@ -760,7 +775,7 @@ impl<A: HalApi> Buffer<A> {
if pending_writes.contains_buffer(self) {
pending_writes.consume_temp(temp);
} else {
let last_submit_index = self.info.submission_index();
let last_submit_index = self.submission_index();
device
.lock_life()
.schedule_resource_destruction(temp, last_submit_index);
@ -792,12 +807,9 @@ pub enum CreateBufferError {
crate::impl_resource_type!(Buffer);
crate::impl_labeled!(Buffer);
crate::impl_storage_item!(Buffer);
crate::impl_trackable!(Buffer);
impl<A: HalApi> Resource for Buffer<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for Buffer<A> {}
impl<A: HalApi> ParentDevice<A> for Buffer<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -866,7 +878,7 @@ pub struct StagingBuffer<A: HalApi> {
pub(crate) device: Arc<Device<A>>,
pub(crate) size: wgt::BufferAddress,
pub(crate) is_coherent: bool,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
}
impl<A: HalApi> Drop for StagingBuffer<A> {
@ -889,12 +901,9 @@ impl<A: HalApi> Labeled for StagingBuffer<A> {
}
}
crate::impl_storage_item!(StagingBuffer);
crate::impl_trackable!(StagingBuffer);
impl<A: HalApi> Resource for StagingBuffer<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for StagingBuffer<A> {}
impl<A: HalApi> ParentDevice<A> for StagingBuffer<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -952,7 +961,7 @@ pub struct Texture<A: HalApi> {
pub(crate) full_range: TextureSelector,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
pub(crate) clear_mode: RwLock<TextureClearMode<A>>,
pub(crate) views: Mutex<Vec<Weak<TextureView<A>>>>,
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
@ -1115,8 +1124,8 @@ impl<A: HalApi> Texture<A> {
views,
bind_groups,
device: Arc::clone(&self.device),
tracker_index: self.info.tracker_index(),
submission_index: self.info.submission_index(),
tracker_index: self.tracker_index(),
submission_index: self.submission_index(),
label: self.label().to_owned(),
}))
};
@ -1126,7 +1135,7 @@ impl<A: HalApi> Texture<A> {
if pending_writes.contains_texture(self) {
pending_writes.consume_temp(temp);
} else {
let last_submit_index = self.info.submission_index();
let last_submit_index = self.submission_index();
device
.lock_life()
.schedule_resource_destruction(temp, last_submit_index);
@ -1427,12 +1436,9 @@ pub enum CreateTextureError {
crate::impl_resource_type!(Texture);
crate::impl_labeled!(Texture);
crate::impl_storage_item!(Texture);
crate::impl_trackable!(Texture);
impl<A: HalApi> Resource for Texture<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for Texture<A> {}
impl<A: HalApi> ParentDevice<A> for Texture<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -1514,7 +1520,7 @@ pub struct TextureView<A: HalApi> {
pub(crate) selector: TextureSelector,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
}
impl<A: HalApi> Drop for TextureView<A> {
@ -1600,12 +1606,9 @@ pub enum TextureViewDestroyError {}
crate::impl_resource_type!(TextureView);
crate::impl_labeled!(TextureView);
crate::impl_storage_item!(TextureView);
crate::impl_trackable!(TextureView);
impl<A: HalApi> Resource for TextureView<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for TextureView<A> {}
impl<A: HalApi> ParentDevice<A> for TextureView<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -1648,7 +1651,7 @@ pub struct Sampler<A: HalApi> {
pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
/// `true` if this is a comparison sampler
pub(crate) comparison: bool,
/// `true` if this is a filtering sampler
@ -1720,12 +1723,9 @@ pub enum CreateSamplerError {
crate::impl_resource_type!(Sampler);
crate::impl_labeled!(Sampler);
crate::impl_storage_item!(Sampler);
crate::impl_trackable!(Sampler);
impl<A: HalApi> Resource for Sampler<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for Sampler<A> {}
impl<A: HalApi> ParentDevice<A> for Sampler<A> {
fn device(&self) -> &Arc<Device<A>> {
@ -1754,7 +1754,7 @@ pub struct QuerySet<A: HalApi> {
pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) info: ResourceInfo,
pub(crate) tracking_data: TrackingData,
pub(crate) desc: wgt::QuerySetDescriptor<()>,
}
@ -1779,12 +1779,9 @@ impl<A: HalApi> ParentDevice<A> for QuerySet<A> {
crate::impl_resource_type!(QuerySet);
crate::impl_labeled!(QuerySet);
crate::impl_storage_item!(QuerySet);
crate::impl_trackable!(QuerySet);
impl<A: HalApi> Resource for QuerySet<A> {
fn as_info(&self) -> &ResourceInfo {
&self.info
}
}
impl<A: HalApi> Resource for QuerySet<A> {}
impl<A: HalApi> QuerySet<A> {
pub(crate) fn raw(&self) -> &A::QuerySet {

View File

@ -11,7 +11,7 @@ use super::{PendingTransition, ResourceTracker, TrackerIndex};
use crate::{
hal_api::HalApi,
lock::{rank, Mutex},
resource::{Buffer, Resource},
resource::{Buffer, Trackable},
resource_log,
snatch::SnatchGuard,
track::{
@ -63,7 +63,7 @@ impl<A: HalApi> BufferBindGroupState<A> {
#[allow(clippy::pattern_type_mismatch)]
pub(crate) fn optimize(&self) {
let mut buffers = self.buffers.lock();
buffers.sort_unstable_by_key(|(b, _)| b.as_info().tracker_index());
buffers.sort_unstable_by_key(|(b, _)| b.tracker_index());
}
/// Returns a list of all buffers tracked. May contain duplicates.
@ -72,7 +72,7 @@ impl<A: HalApi> BufferBindGroupState<A> {
let buffers = self.buffers.lock();
buffers
.iter()
.map(|(ref b, _)| b.as_info().tracker_index())
.map(|(ref b, _)| b.tracker_index())
.collect::<Vec<_>>()
.into_iter()
}
@ -161,7 +161,7 @@ impl<A: HalApi> BufferUsageScope<A> {
) -> Result<(), ResourceUsageCompatibilityError> {
let buffers = bind_group.buffers.lock();
for &(ref resource, state) in &*buffers {
let index = resource.as_info().tracker_index().as_usize();
let index = resource.tracker_index().as_usize();
unsafe {
insert_or_merge(
@ -233,7 +233,7 @@ impl<A: HalApi> BufferUsageScope<A> {
buffer: &Arc<Buffer<A>>,
new_state: BufferUses,
) -> Result<(), ResourceUsageCompatibilityError> {
let index = buffer.info.tracker_index().as_usize();
let index = buffer.tracker_index().as_usize();
self.allow_index(index);
@ -388,7 +388,7 @@ impl<A: HalApi> BufferTracker<A> {
/// If the ID is higher than the length of internal vectors,
/// the vectors will be extended. A call to set_size is not needed.
pub fn insert_single(&mut self, resource: Arc<Buffer<A>>, state: BufferUses) {
let index = resource.info.tracker_index().as_usize();
let index = resource.tracker_index().as_usize();
self.allow_index(index);
@ -427,7 +427,7 @@ impl<A: HalApi> BufferTracker<A> {
buffer: &Arc<Buffer<A>>,
state: BufferUses,
) -> Option<PendingTransition<BufferUses>> {
let index: usize = buffer.as_info().tracker_index().as_usize();
let index: usize = buffer.tracker_index().as_usize();
self.allow_index(index);

View File

@ -126,11 +126,7 @@ use wgt::strict_assert_ne;
pub(crate) struct TrackerIndex(u32);
impl TrackerIndex {
/// A dummy value to place in ResourceInfo for resources that are never tracked.
pub const INVALID: Self = TrackerIndex(u32::MAX);
pub fn as_usize(self) -> usize {
debug_assert!(self != Self::INVALID);
self.0 as usize
}
}

View File

@ -8,7 +8,7 @@ use std::sync::Arc;
use crate::{
lock::{rank, Mutex},
resource::Resource,
resource::Trackable,
resource_log,
track::ResourceMetadata,
};
@ -17,11 +17,11 @@ use super::{ResourceTracker, TrackerIndex};
/// Stores all the resources that a bind group stores.
#[derive(Debug)]
pub(crate) struct StatelessBindGroupState<T: Resource> {
pub(crate) struct StatelessBindGroupState<T: Trackable> {
resources: Mutex<Vec<Arc<T>>>,
}
impl<T: Resource> StatelessBindGroupState<T> {
impl<T: Trackable> StatelessBindGroupState<T> {
pub fn new() -> Self {
Self {
resources: Mutex::new(rank::STATELESS_BIND_GROUP_STATE_RESOURCES, Vec::new()),
@ -34,7 +34,7 @@ impl<T: Resource> StatelessBindGroupState<T> {
/// accesses will be in a constant ascending order.
pub(crate) fn optimize(&self) {
let mut resources = self.resources.lock();
resources.sort_unstable_by_key(|resource| resource.as_info().tracker_index());
resources.sort_unstable_by_key(|resource| resource.tracker_index());
}
/// Returns a list of all resources tracked. May contain duplicates.
@ -58,11 +58,11 @@ impl<T: Resource> StatelessBindGroupState<T> {
/// Stores all resource state within a command buffer or device.
#[derive(Debug)]
pub(crate) struct StatelessTracker<T: Resource> {
pub(crate) struct StatelessTracker<T: Trackable> {
metadata: ResourceMetadata<T>,
}
impl<T: Resource> ResourceTracker for StatelessTracker<T> {
impl<T: Trackable> ResourceTracker for StatelessTracker<T> {
/// Try to remove the given resource from the tracker iff we have the last reference to the
/// resource and the epoch matches.
///
@ -115,7 +115,7 @@ impl<T: Resource> ResourceTracker for StatelessTracker<T> {
}
}
impl<T: Resource> StatelessTracker<T> {
impl<T: Trackable> StatelessTracker<T> {
pub fn new() -> Self {
Self {
metadata: ResourceMetadata::new(),
@ -162,7 +162,7 @@ impl<T: Resource> StatelessTracker<T> {
/// Returns a reference to the newly inserted resource.
/// (This allows avoiding a clone/reference count increase in many cases.)
pub fn insert_single(&mut self, resource: Arc<T>) -> &Arc<T> {
let index = resource.as_info().tracker_index().as_usize();
let index = resource.tracker_index().as_usize();
self.allow_index(index);
@ -176,7 +176,7 @@ impl<T: Resource> StatelessTracker<T> {
/// If the ID is higher than the length of internal vectors,
/// the vectors will be extended. A call to set_size is not needed.
pub fn add_single(&mut self, resource: &Arc<T>) {
let index = resource.as_info().tracker_index().as_usize();
let index = resource.tracker_index().as_usize();
self.allow_index(index);

View File

@ -25,7 +25,7 @@ use super::{
use crate::{
hal_api::HalApi,
lock::{rank, Mutex},
resource::{Labeled, Resource, Texture, TextureInner},
resource::{Labeled, Texture, TextureInner, Trackable},
resource_log,
snatch::SnatchGuard,
track::{
@ -175,7 +175,7 @@ impl<A: HalApi> TextureBindGroupState<A> {
/// accesses will be in a constant ascending order.
pub(crate) fn optimize(&self) {
let mut textures = self.textures.lock();
textures.sort_unstable_by_key(|v| v.texture.as_info().tracker_index());
textures.sort_unstable_by_key(|v| v.texture.tracker_index());
}
/// Returns a list of all textures tracked. May contain duplicates.
@ -370,7 +370,7 @@ impl<A: HalApi> TextureUsageScope<A> {
selector: Option<TextureSelector>,
new_state: TextureUses,
) -> Result<(), ResourceUsageCompatibilityError> {
let index = texture.as_info().tracker_index().as_usize();
let index = texture.tracker_index().as_usize();
self.tracker_assert_in_bounds(index);
@ -538,7 +538,7 @@ impl<A: HalApi> TextureTracker<A> {
/// If the ID is higher than the length of internal vectors,
/// the vectors will be extended. A call to set_size is not needed.
pub fn insert_single(&mut self, resource: Arc<Texture<A>>, usage: TextureUses) {
let index = resource.info.tracker_index().as_usize();
let index = resource.tracker_index().as_usize();
self.allow_index(index);
@ -579,7 +579,7 @@ impl<A: HalApi> TextureTracker<A> {
selector: TextureSelector,
new_state: TextureUses,
) -> Drain<'_, PendingTransition<TextureUses>> {
let index = texture.as_info().tracker_index().as_usize();
let index = texture.tracker_index().as_usize();
self.allow_index(index);
@ -713,7 +713,7 @@ impl<A: HalApi> TextureTracker<A> {
let textures = bind_group_state.textures.lock();
for t in textures.iter() {
let index = t.texture.as_info().tracker_index().as_usize();
let index = t.texture.tracker_index().as_usize();
scope.tracker_assert_in_bounds(index);
if unsafe { !scope.metadata.contains_unchecked(index) } {