#Dependency between input attachment and color attachment output of 2nd subpass

9 messages · Page 1 of 1 (latest)

dry ocean
#

Hello guys,
I have a question related to the dependency of a renderpass with 2 subpasses

in the first pass i render some stuff to a color attachment of an image i created exactly for this render pass. it's not used anywhere else

        dependencies[0].src_subpass = vk::SUBPASS_EXTERNAL;
        dependencies[0].dst_subpass = 0;
        dependencies[0].src_stage_mask = vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT;
        dependencies[0].src_access_mask = vk::AccessFlags::empty();
        dependencies[0].dst_stage_mask = vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT;
        dependencies[0].dst_access_mask = vk::AccessFlags::COLOR_ATTACHMENT_WRITE;
        dependencies[0].dependency_flags = vk::DependencyFlags::BY_REGION;

This is clear to me

Now comes the second subpass. I this subpass i read the memory written in subpass 0 inside the fragment shader.
To make it work i used this: (note i understand that memory read and memory write are not the optimal access mask. but my question is about something else)


        dependencies[1].src_subpass = 0;
        dependencies[1].dst_subpass = 1;
        dependencies[1].src_stage_mask = vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT;
        dependencies[1].src_access_mask = vk::AccessFlags::COLOR_ATTACHMENT_WRITE;
        dependencies[1].dst_stage_mask = vk::PipelineStageFlags::FRAGMENT_SHADER
            | vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT;
        dependencies[1].dst_access_mask =
            vk::AccessFlags::MEMORY_READ | vk::AccessFlags::MEMORY_WRITE;

And it works.

#

Now my question:
I try to formulate what i want in english, since maybe I have a understanding problem somewhere:
I thought about what happens under the hood:
Subpass 0: render stuff -> write to attachment
Subpass 1: previous attachment gets input attachment -> the fragment shader reads this attachment -> goes into the color attachment stage, writes its content

So i wondered if i cannot change the dependency like this:
Subpass 0: render stuff -> write to attachment
Subpass 1: previous attachment gets input attachment -> the fragment shader reads this attachment

Since color attachment stage always happens after the fragment stage, why should i specify the vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT flag in dst_stage_mask of dependency 1.

Instead i tried to make a third dependency that (extremly simplified) just makes sure any external operations are properly synced


        dependencies[2].src_subpass = vk::SUBPASS_EXTERNAL;
        dependencies[2].dst_subpass = 1;
        dependencies[2].src_stage_mask = vk::PipelineStageFlags::ALL_GRAPHICS;
        dependencies[2].src_access_mask =
            vk::AccessFlags::MEMORY_WRITE | vk::AccessFlags::MEMORY_READ;
        dependencies[2].dst_stage_mask = vk::PipelineStageFlags::ALL_GRAPHICS;
        dependencies[2].dst_access_mask =
            vk::AccessFlags::MEMORY_WRITE | vk::AccessFlags::MEMORY_READ;
        dependencies[2].dependency_flags = vk::DependencyFlags::BY_REGION;
#

I get

'Validation Error: [ SYNC-HAZARD-WRITE-AFTER-WRITE ] Object 0: handle = 0x6a000000006a, type = VK_OBJECT_TYPE_RENDER_PASS; | MessageID = 0x5c0ec5d6 | vkCmdEndRenderPass: Hazard WRITE_AFTER_WRITE in subpass 1 for attachment 1 color aspect during store with storeOp VK_ATTACHMENT_STORE_OP_DONT_CARE. Access info (usage: SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE, prior_usage: SYNC_IMAGE_LAYOUT_TRANSITION, write_barriers: SYNC_FRAGMENT_SHADER_ACCELERATION_STRUCTURE_READ|SYNC_FRAGMENT_SHADER_COLOR_ATTACHMENT_READ|SYNC_FRAGMENT_SHADER_DEPTH_STENCIL_ATTACHMENT_READ|SYNC_FRAGMENT_SHADER_DESCRIPTOR_BUFFER_READ_EXT|SYNC_FRAGMENT_SHADER_INPUT_ATTACHMENT_READ|SYNC_FRAGMENT_SHADER_SHADER_BINDING_TABLE_READ|SYNC_FRAGMENT_SHADER_SHADER_SAMPLED_READ|SYNC_FRAGMENT_SHADER_SHADER_STORAGE_READ|SYNC_FRAGMENT_SHADER_SHADER_STORAGE_WRITE|SYNC_FRAGMENT_SHADER_UNIFORM_READ, command: vkCmdNextSubpass, seq_no: 3, subcmd: 1,renderpass: VkRenderPass 0x6a000000006a[], reset_no: 2)'

This error indicates that it is related to the input attachment's layout transition.
It happens as soon as i remove the vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT flag.
Why is the color attachment stage important here?

In dependency 1 I already specified that all writes to the color attachment from subpass 0 must be flushed (src stage and access mask), before reading or writing inside the fragment stage (dst stage & access mask).

I am clearly lacking some understanding, but it's hard for me to imagine it.

how is the dst color attachment stage of subpass 1 related to reading the color attachment of subpass 0 inside the fragment shader of subpass 1

elfin socket
#

Layout transitions are a read/write operation at color attachment output (or early/late fragment tests for d/s attachments).
It looks like you're doing a STORE_OP_DONT_CARE, but also doing a layout transition between the last usage in a subpass and the finalLayout and this layout transition isn't synced correctly.

#

Doing this transition seems pointless as DONT_CARE is trashing the contents anyway.

(Remember that next time you use that image, you can set the initialLayout to undefined, which is always allowed but will trash the content. Since the DONT_CARE trashed the contents anyway, this is moot but might make your code simpler instead of having to track the actual layout)

dry ocean
# elfin socket Doing this transition seems pointless as DONT_CARE is trashing the contents anyw...

the intial layout is undefined. final layout can't be undefined according the spec. i guess it has to be color attachment anyway tho. since that's the layout it will use in the next frame again.

I thought about this problem for a while now, and you are right the transition back to the color attachment is one of the problems:

So if i imagine what is happening to the image, it looks like this:

  1. subpass 0: write to img (as color attachment)
  2. subpass 1: transition to shader read
  3. end of renderpass: transition back to color attachment to start 1. again

i tried to add a dependency from subpass 1 to vk::SUBPASS_EXTERNAL

but that sadly didnt do the trick

how would a dependency look like that supports transitioning back to the original format?
i don't understand that adding | vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT to dst_stage_mask in dependency 1 fixes this layout transition problem

doesn't the layout only matter at the end of the render pass.. actually even only in the next frame?

elfin socket
#

Don't transition back to the initial format. If the initial layout is undefined it's fine to leave it in the 'wrong' layout as finalLayout in the previous frame. If you must, you need color attachment output in the flags as transitions (for color formats) happen as color attachment read/writes

dry ocean
elfin socket
#

Whatever the layout is in the last subpass yeah.