From 38305c62f3228cb8378508d401856101cc0a7d27 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sun, 15 Dec 2019 23:10:38 -0500 Subject: [PATCH] Fix tracking of render pass attachments --- wgpu-core/src/command/compute.rs | 1 + wgpu-core/src/command/mod.rs | 71 ++++++++++++++++++-------------- wgpu-core/src/command/render.rs | 2 + wgpu-core/src/device.rs | 5 +++ wgpu-core/src/track/mod.rs | 25 +++++++---- 5 files changed, 66 insertions(+), 38 deletions(-) diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 9da26c2781..3079e03e86 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -56,6 +56,7 @@ impl> Global { // There are no transitions to be made: we've already been inserting barriers // into the parent command buffer while recording this compute pass. + log::debug!("Compute pass {:?} tracker: {:#?}", pass_id, pass.trackers); cmb.trackers = pass.trackers; cmb.raw.push(pass.raw); } diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 5fd4719426..eebd85b433 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -196,6 +196,7 @@ impl Global { if let Some((ref view_id, _)) = comb.used_swap_chain { comb.trackers.views.remove(view_id.value); } + log::debug!("Command buffer {:?} tracker: {:#?}", encoder_id, comb.trackers); encoder_id } } @@ -280,8 +281,18 @@ impl> Global { let texture = &texture_guard[texture_id]; assert!(texture.usage.contains(TextureUsage::OUTPUT_ATTACHMENT)); - let old_layout = match trackers.textures.query(texture_id, view.range.clone()) { + let consistent_usage = trackers.textures.query(texture_id, view.range.clone()); + let pending = trackers.textures.change_replace( + texture_id, + &texture.life_guard.ref_count, + view.range.clone(), + TextureUsage::OUTPUT_ATTACHMENT, + &texture.full_range, + ); + + let old_layout = match consistent_usage { Some(usage) => { + // Using render pass for transition. conv::map_texture_state( usage, hal::format::Aspects::DEPTH | hal::format::Aspects::STENCIL, @@ -291,14 +302,6 @@ impl> Global { None => { // Required sub-resources have inconsistent states, we need to // issue individual barriers instead of relying on the render pass. - let pending = trackers.textures.change_replace( - texture_id, - &texture.life_guard.ref_count, - view.range.clone(), - TextureUsage::OUTPUT_ATTACHMENT, - &texture.full_range, - ); - barriers.extend(pending.map(|pending| { log::trace!("\tdepth-stencil {:?}", pending); hal::memory::Barrier::Image { @@ -349,23 +352,26 @@ impl> Global { let texture = &texture_guard[source_id.value]; assert!(texture.usage.contains(TextureUsage::OUTPUT_ATTACHMENT)); - let old_layout = match trackers - .textures - .query(source_id.value, view.range.clone()) - { + let consistent_usage = trackers.textures.query( + source_id.value, + view.range.clone(), + ); + let pending = trackers.textures.change_replace( + source_id.value, + &texture.life_guard.ref_count, + view.range.clone(), + TextureUsage::OUTPUT_ATTACHMENT, + &texture.full_range, + ); + + let old_layout = match consistent_usage { Some(usage) => { + // Using render pass for transition. conv::map_texture_state(usage, hal::format::Aspects::COLOR).1 } None => { // Required sub-resources have inconsistent states, we need to // issue individual barriers instead of relying on the render pass. - let pending = trackers.textures.change_replace( - source_id.value, - &texture.life_guard.ref_count, - view.range.clone(), - TextureUsage::OUTPUT_ATTACHMENT, - &texture.full_range, - ); barriers.extend(pending.map(|pending| { log::trace!("\tcolor {:?}", pending); hal::memory::Barrier::Image { @@ -432,23 +438,26 @@ impl> Global { let texture = &texture_guard[source_id.value]; assert!(texture.usage.contains(TextureUsage::OUTPUT_ATTACHMENT)); - let old_layout = match trackers - .textures - .query(source_id.value, view.range.clone()) - { + let consistent_usage = trackers.textures.query( + source_id.value, + view.range.clone(), + ); + let pending = trackers.textures.change_replace( + source_id.value, + &texture.life_guard.ref_count, + view.range.clone(), + TextureUsage::OUTPUT_ATTACHMENT, + &texture.full_range, + ); + + let old_layout = match consistent_usage { Some(usage) => { + // Using render pass for transition. conv::map_texture_state(usage, hal::format::Aspects::COLOR).1 } None => { // Required sub-resources have inconsistent states, we need to // issue individual barriers instead of relying on the render pass. - let pending = trackers.textures.change_replace( - source_id.value, - &texture.life_guard.ref_count, - view.range.clone(), - TextureUsage::OUTPUT_ATTACHMENT, - &texture.full_range, - ); barriers.extend(pending.map(|pending| { log::trace!("\tresolve {:?}", pending); hal::memory::Barrier::Image { diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 1f5434684c..4609297800 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -185,6 +185,8 @@ impl> Global { pass.raw.end_render_pass(); } pass.trackers.optimize(); + log::debug!("Render pass {:?} tracker: {:#?}", pass_id, pass.trackers); + let cmb = &mut cmb_guard[pass.cmb_id.value]; let (buffer_guard, mut token) = hub.buffers.read(&mut token); let (texture_guard, _) = hub.textures.read(&mut token); diff --git a/wgpu-core/src/device.rs b/wgpu-core/src/device.rs index e5ddab3cb6..d55c8d2d29 100644 --- a/wgpu-core/src/device.rs +++ b/wgpu-core/src/device.rs @@ -1427,6 +1427,9 @@ impl> Global { let id = hub .bind_groups .register_identity(id_in, bind_group, &mut token); + log::debug!("Bind group {:?} tracker : {:#?}", + id, hub.bind_groups.read(&mut token).0[id].used); + let ok = device .trackers .lock() @@ -1628,6 +1631,8 @@ impl> Global { } } + log::debug!("Device tracker after submission: {:#?}", trackers); + // now prepare the GPU submission let fence = device.raw.create_fence(false).unwrap(); let submission = hal::queue::Submission::<_, _, Vec<&B::Semaphore>> { diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index 6291d7b135..8decc623a3 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -19,7 +19,7 @@ use crate::{ use std::{ borrow::Borrow, collections::hash_map::Entry, - fmt::Debug, + fmt, marker::PhantomData, ops::Range, vec::Drain, @@ -75,11 +75,11 @@ pub enum Stitch { /// a particular resource type, like a buffer or a texture. pub trait ResourceState: Clone { /// Corresponding `HUB` identifier. - type Id: Copy + Debug + TypedId; + type Id: Copy + fmt::Debug + TypedId; /// A type specifying the sub-resources. - type Selector: Debug; + type Selector: fmt::Debug; /// Usage type for a `Unit` of a sub-resource. - type Usage: Debug; + type Usage: fmt::Debug; /// Create a new resource state to track the specified subresources. fn new(full_selector: &Self::Selector) -> Self; @@ -137,7 +137,7 @@ pub trait ResourceState: Clone { /// Structure wrapping the abstract tracking state with the relevant resource /// data, such as the reference count and the epoch. -#[derive(Clone, Debug)] +#[derive(Clone)] struct Resource { ref_count: RefCount, state: S, @@ -155,7 +155,6 @@ pub struct PendingTransition { } /// A tracker for all resources of a given type. -#[derive(Debug)] pub struct ResourceTracker { /// An association of known resource indices with their tracked states. map: FastHashMap>, @@ -165,6 +164,18 @@ pub struct ResourceTracker { backend: Backend, } +impl fmt::Debug for ResourceTracker { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.map + .iter() + .map(|(&index, res)| { + ((index, res.epoch), &res.state) + }) + .collect::>() + .fmt(formatter) + } +} + impl ResourceTracker { /// Create a new empty tracker. pub fn new(backend: Backend) -> Self { @@ -388,7 +399,7 @@ impl ResourceTracker { } -impl ResourceState for PhantomData { +impl ResourceState for PhantomData { type Id = I; type Selector = (); type Usage = ();