From 7b6da19a77c9f289115865913cee8c18867bcf54 Mon Sep 17 00:00:00 2001 From: janis Date: Tue, 14 Apr 2026 22:52:54 +0200 Subject: [PATCH] i think fixed logic in access conflict? --- crates/renderer/src/render_graph/commands.rs | 5 +++ crates/renderer/src/render_graph/resources.rs | 33 ++++++++++++------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/crates/renderer/src/render_graph/commands.rs b/crates/renderer/src/render_graph/commands.rs index df93dae..3cacc5a 100644 --- a/crates/renderer/src/render_graph/commands.rs +++ b/crates/renderer/src/render_graph/commands.rs @@ -308,6 +308,11 @@ pub struct BeginRendering { impl Command for BeginRendering { fn side_effects(&self, mut map: SideEffectMap) { for attachment in &self.color_attachments { + // The dependencies declared here need to be barrier'd before the + // render pass: the spec says pipelineBarrier inside of a render + // pass instance referencing framebuffer-local stages must contain + // only framebuffer-local stages. + // TODO: consider loadop and storeop? attachment.side_effect(map.reborrow().into_side_effect_map2( vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT, diff --git a/crates/renderer/src/render_graph/resources.rs b/crates/renderer/src/render_graph/resources.rs index 34e54fd..8019985 100644 --- a/crates/renderer/src/render_graph/resources.rs +++ b/crates/renderer/src/render_graph/resources.rs @@ -201,7 +201,13 @@ impl ResourceAccess { .. }, ) => { - if aspect != aspect_b + // two accesses conflict if they overlap; + // they overlap if they share mip levels or array layers with + // the same aspects. + // If one access contains the other, we can merge them (i + // think), however: if a previous access requires a less general + // barrier, then is it better to split? + if !aspect.contains(*aspect_b) || layout != layout_b || !mip_level.intersects(mip_level_b) || !array_layers.intersects(array_layers_b) @@ -209,6 +215,7 @@ impl ResourceAccess { return false; } + *aspect = *aspect | *aspect_b; *mip_level = mip_level.union(mip_level_b); *array_layers = array_layers.union(array_layers_b); // let lower_left = Offset::from(*origin).min(Offset::from(*origin_b)); @@ -245,7 +252,7 @@ impl ResourceAccess { return false; } - // must be a read/write conflict, check if subresources intersect + // must be a read/write conflict, check if sub-resources intersect !(*offset > *offset_b + *size_b || *offset_b > *offset + *size) } ( @@ -264,21 +271,23 @@ impl ResourceAccess { .. }, ) => { - // layouts differing means we need a layout transition, which is a conflict + // check if sub-resources intersect + let overlaps = aspect.intersects(*aspect_b) + && (mip_level.intersects(mip_level_b) + || array_layers.intersects(array_layers_b)); + + // non-overlapping sub-resources never conflict + if !overlaps { + return false; + } + + // layout transition required even on reads if layout != layout_b { return true; } // two reads don't conflict - // TODO: two writes may conflict if the user cares about the order of writes. - if access_flag_is_read(self.access) == access_flag_is_read(other.access) { - return false; - } - - // must be a read/write conflict, check if subresources intersect - aspect.intersects(*aspect_b) - && (mip_level.intersects(mip_level_b) - || array_layers.intersects(array_layers_b)) + access_flag_is_read(self.access) != access_flag_is_read(other.access) } } }