i think fixed logic in access conflict?

This commit is contained in:
janis 2026-04-14 22:52:54 +02:00
parent 28c4f52a2b
commit 7b6da19a77
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
2 changed files with 26 additions and 12 deletions

View file

@ -308,6 +308,11 @@ pub struct BeginRendering {
impl Command for BeginRendering { impl Command for BeginRendering {
fn side_effects(&self, mut map: SideEffectMap) { fn side_effects(&self, mut map: SideEffectMap) {
for attachment in &self.color_attachments { 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? // TODO: consider loadop and storeop?
attachment.side_effect(map.reborrow().into_side_effect_map2( attachment.side_effect(map.reborrow().into_side_effect_map2(
vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT, vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,

View file

@ -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 || layout != layout_b
|| !mip_level.intersects(mip_level_b) || !mip_level.intersects(mip_level_b)
|| !array_layers.intersects(array_layers_b) || !array_layers.intersects(array_layers_b)
@ -209,6 +215,7 @@ impl ResourceAccess {
return false; return false;
} }
*aspect = *aspect | *aspect_b;
*mip_level = mip_level.union(mip_level_b); *mip_level = mip_level.union(mip_level_b);
*array_layers = array_layers.union(array_layers_b); *array_layers = array_layers.union(array_layers_b);
// let lower_left = Offset::from(*origin).min(Offset::from(*origin_b)); // let lower_left = Offset::from(*origin).min(Offset::from(*origin_b));
@ -245,7 +252,7 @@ impl ResourceAccess {
return false; 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) !(*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 { if layout != layout_b {
return true; return true;
} }
// two reads don't conflict // two reads don't conflict
// TODO: two writes may conflict if the user cares about the order of writes. access_flag_is_read(self.access) != access_flag_is_read(other.access)
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))
} }
} }
} }