1
votes

Now, I want to do post-processing and use subpass way to do it. I have created two subpasses and draw a big triangle in the screen in the second subpass.

But the problem is I don't how to get the render result of the first subpass because I need to feed it to the fragment shader of the second subpass, and then I can do some effect in the fragment shader of the second subpass.

I guess the result is swapchain_imageView. But I cannot use it. Vulkan show me that Cannot use image 0x8 with specific layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL that doesn't match the actual current layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL. I guess the way is wrong.

How to get the correct render result for next subpass?

2
VkAttachmentReference inputAttachmentRef = {}; inputAttachmentRef.attachment = 0; inputAttachmentRef.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; VkSubpassDescription subpass2 = {}; subpass2.inputAttachmentCount = 1; subpass2.pInputAttachments = &inputAttachmentRef; Because I set inputAttachment in subpass 2, I guess the system should send the render result of the subpass 1 to my fragment shader of the subpass 2 automatically. But I just guess. I really don't know about it. - user8201562

2 Answers

3
votes

You want a renderpass with subpass attachment references and dependencies like this:

pSubpasses = [
  {
    pInputAttachments = [],
    pColorAttachments = [{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}]
  },
  {
    pInputAttachments = [{0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}]
    pColorAttachments = [{1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}]
  }
]

pDependencies = [
  {
    0, 1,
    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
    VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
    VK_DEPENDENCY_BY_REGION_BIT,
  }
]

In the second subpass, you also need to bind the image in attachment 0 to the fragment shader using a VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT descriptor.

In the shader, the input attachment is used like:

layout (input_attachment_index=i, set=m, binding=n) uniform subpassInput inputAttachment;
vec4 fragment = subpassLoad(inputAttachment);
0
votes

You cannot arbitrarily read from any image that is currently an attachment of a render pass. Note that I said "render pass", not "subpass". Once you start a render pass image, those images are off-limits for any operation that is not explicitly an attachment operation.

If your post-processing effect is one that only needs to do read/modify/write operations on each texel of the image, if it doesn't need to read neighboring pixels in order to do its job, then you can use the image as an input attachment. This would be for effects like tone mapping and the like.

But if you do need to access multiple texels from the rendered image, then this post-processing effect must exist in a separate render pass instance from the one that created it.

Also:

Because I set inputAttachment in subpass 2, I guess the system should send the render result of the subpass 1 to my fragment shader of the subpass 2 automatically.

You "guess"? This is Vulkan; there is no "guessing" here. Unless you told the system that there was a dependency between these operations, then there won't be. And therefore trying to read from it is UB.

If subpass 2 is going to read an input attachment written by subpass 1, then you must place a subpass dependency from subpass 1 to subpass 2. It's probably best to use a "by-region" dependency (unless you're reading other stuff written in previous subpasses).