4

I am trying to use the color attachment created in subpass 0 as an input attachment in subpass 1. However there is an issue that i cant get past.

My problem currently is the following, i try to clear attachment 0 at the beginning of the pass using VK_ATTACHMENT_LOAD_OP_CLEAR however gives the error.

Cannot clear attachment 0 with invalid first layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.

Which seems weird to me, attachment 0 does not get layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL untill subpass 1 where it is a input attachment, while the clear should have already happened when the layout was still VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (AFAIK).

I have now tried to just continue running after the validation error, and attachment 0 does get cleared, which makes me even more unsure. I can apparently just ignore the validation error, but something weird might be going on that could cause problems later on so I am not confidant enough to just ignore it.

Here is the minimal code that will give the error:


VkAttachmentDescription attachments[1] {};
attachments[0].format = VK_FORMAT_R16G16B16A16_SFLOAT;
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

VkAttachmentReference pass_0_ColorAttachments[1];
pass_0_ColorAttachments[0].attachment = 0;
pass_0_ColorAttachments[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

VkAttachmentReference pass_1_InputAttachments[1];
pass_1_InputAttachments[0].attachment = 0;
pass_1_InputAttachments[0].layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;

VkSubpassDescription subpasses[2] {};

subpasses[0].colorAttachmentCount = 1;
subpasses[0].pColorAttachments = pass_0_ColorAttachments;
subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;

subpasses[1].inputAttachmentCount = 1;
subpasses[1].pInputAttachments = pass_1_InputAttachments;
subpasses[1].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;

VkSubpassDependency subpassDependancies[1] {};
subpassDependancies[0].srcSubpass = 0;
subpassDependancies[0].dstSubpass = 1;
subpassDependancies[0].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassDependancies[0].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
subpassDependancies[0].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassDependancies[0].dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
subpassDependancies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

VkRenderPassCreateInfo renderpassCreateInfo {};
renderpassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderpassCreateInfo.attachmentCount = 1;
renderpassCreateInfo.pAttachments = attachments;
renderpassCreateInfo.subpassCount = 2;
renderpassCreateInfo.pSubpasses = subpasses;
renderpassCreateInfo.dependencyCount = 1;
renderpassCreateInfo.pDependencies = subpassDependancies;

VkRenderPass renderPass;
vkCreateRenderPass(device, &renderpassCreateInfo, nullptr, &renderPass);

The next part is only relevant if it is impossible to specify VK_ATTACHMENT_LOAD_OP_CLEAR for an attachment used as color attachment first and in a later subpass as input attachment (i see no reason why this would be impossible, unless vulkan does the load operation each subpass). So this is kind of a separate problem.

I could, instead of using VK_ATTACHMENT_LOAD_OP_CLEAR, manually clear the attachment using vkCmdClearAttachments and use VK_ATTACHMENT_LOAD_OP_DONT_CARE for the load operation of the attachment.

I have a crash error on calling vkCmdClearAttachments I started the command buffer recording and the renderpass, and in the first subpass I call:

VkClearAttachment clearAtts[] = {{VK_IMAGE_ASPECT_COLOR_BIT, 1, {0,0,0,0}}}; VkClearRect rect = {{{0,0}, {1,1}}, 0, 1}; vkCmdClearAttachments(vkCommandBuffer, 1, clearAtts, 1, &rect); {1,1} as the extent to show this is not the problem

8
  • "And then changing the layout between the subpasses with a barrier. [...] But it seems I HAVE to use these different layouts for vulkan to even accept the renderpass creation." I don't quite understand that. You can't put a pipeline barrier in renderpass creation. You can (and have to) create a subpass dependency. But that's different from a pipeline barrier. So which one are you talking about? Commented Jul 31, 2016 at 1:20
  • I edited the question, I think it should be clear this way. In short: I use different layouts for the discriptions of the input and color attachment of the respective subpasses pointing to the same image. And thus later a barrier is needed to change the layout. Commented Jul 31, 2016 at 1:30
  • That didn't clear it up. When you say "forcing me to later use a barrier to switch the layout", do you mean a vkCmdPipelineBarrier, or do you mean a VkSubpassDependency? If it's the latter, then show us what that dependency looks like. Commented Jul 31, 2016 at 1:31
  • 1
    Indeed, you need to show us everything you pass to vkCreateRenderPass. The error you say the validation layer is giving you shouldn't happen unless you've done something wrong somewhere. And where that is isn't in code you've shown us. Commented Jul 31, 2016 at 1:41
  • 1
    Ah that about the dependency taking care of the layout conversion was indeed something i missed. So now the main problem is what VkAttachmentLoadOp to use so the attachment gets cleared on start of subpass 0. And you mean that the error about the clear op should not appear? I will extend the question as you asked tomorrow. Commented Jul 31, 2016 at 1:51

1 Answer 1

5

You're having the same problem as was discovered here. It's a bug in the validation layer in 1.0.17. It would appear that the current Github head has a fix, but that fix is not in the 1.0.21 release.

But you still need to fix the stuff below ;)


subpassDependancies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;

You are not going to read the image as a color attachment. You're going to read it as an input attachment. From the fragment shader. So that would mean VK_ACCESS_INPUT_ATTACHMENT_READ_BIT.

If that fixes the error, then I'd guess the validation layer got confused by your oddball dependency access mask. It therefore couldn't establish a valid dependency chain between subpasses 0 and 1, and thus thought that subpass 1 was first.

Also, your srcStageMask and dstStageMask bits are way over-specified. Every graphics stage is not going to write to the image, and every graphics stage is not going to access it after. You only wrote to the image as a color attachment, and you're only going to read from it in the fragment shader.

So your srcStageMask ought to just be VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, and your dstStageMask ought to be VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT.

Sign up to request clarification or add additional context in comments.

3 Comments

Using the changes you suggested has no effect on the error. Is there any chance this could be a driver bug? I'm using a firepro m2000 (HD Radeon 7700M series, vulkan 1.0.17)
@BartVerberne: It's an error from a validation layer. Those are never part of the driver.
I have made the question clearer, also the clear operation actually does work if i continue after the error (i used to halt my program on validation errors because usually this would case a near immediate crash)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.