Bähny
Bähny

Reputation: 35

Is there any constraint where to add the subpass dependency?

I have the following setup: One renderpass draws to a texture and the second renderpass draws to a different texture and reads the first one.

To avoid artifacts I added a subpass dependency to the first render pass: (C# SharpVulkan like code)

SubpassDependency subpassDependency = new SubpassDependency()
{
    SourceSubpass = 0,
    DestinationSubpass = (~0U),//aka VK_SUBPASS_EXTERNAL
    SourceAccessMask = AccessFlags.ColorAttachmentWrite,
    SourceStageMask = PipelineStageFlags.ColorAttachmentOutput,
    DestinationAccessMask = AccessFlags.ShaderRead,
    DestinationStageMask = PipelineStageFlags.FragmentShader,
    DependencyFlags = DependencyFlags.ByRegion,
};

This expresses the dependency "The fragment shader of the following renderpass waits until the current render pass finished rendering."

If I try to model the same dependency the other way around "The fragment shader of the current render pass waits until the previous render pass finished rendering" the synchronization fails and I have artifacts in the final image.

SubpassDependency subpassDependency = new SubpassDependency()
{
    SourceSubpass = (~0U),//VK_SUBPASS_EXTERNAL,
    DestinationSubpass = 0,
    SourceAccessMask = AccessFlags.ColorAttachmentWrite,
    SourceStageMask = PipelineStageFlags.ColorAttachmentOutput,
    DestinationAccessMask = AccessFlags.ShaderRead,
    DestinationStageMask = PipelineStageFlags.FragmentShader,
    DependencyFlags = DependencyFlags.ByRegion,
};

Quote from the specification:

If srcSubpass is equal to VK_SUBPASS_EXTERNAL, the first synchronization scope includes commands submitted to the queue before the render pass instance began.

I dont understand why the second approach is not working and what are the constraints for the subpass dependency to work. Is there something in the specification I missed ?

Upvotes: 0

Views: 265

Answers (1)

krOoze
krOoze

Reputation: 13246

If you skip the external dependency in the first renderpass, then a default one is provided. It has dstStageMask of VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT. The automatic transfer to the finalLayout is only guaranteed to happen-before the visibility operation of the external dependency (so, before BOTTOM_OF_PIPE).

In the second renderpass you specify srcStageMask of VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, so I would think there is a race condition between the transfer to finalLayout and first use in the second renderpass.

Upvotes: 1

Related Questions