I am trying to do two simple subpasses, where the second one has a dependency on the first one.
//subpass 1
VkAttachmentReference colorReferences = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
VkSubpassDescription subpass1 = {};
subpass1.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass1.pColorAttachments = &colorReferences;
subpass1.colorAttachmentCount = 1;
//subpass 2
VkAttachmentReference inputRefernce = { 0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
VkSubpassDescription subpass2 = {};
subpass2.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass2.inputAttachmentCount = 1;
subpass2.pInputAttachments = &inputRefernce;
//Render pass
VkAttachmentDescription attachmentDescs = {};
attachmentDescs.samples = VK_SAMPLE_COUNT_1_BIT;
attachmentDescs.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachmentDescs.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachmentDescs.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescs.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescs.format = VK_FORMAT_R16G16B16A16_SFLOAT;
attachmentDescs.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescs.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDependency dependency = {};
dependency.srcSubpass = 0;
dependency.dstSubpass = 1;
dependency.srcStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependency.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
VkSubpassDescription subpasses[2] = { subpass1, subpass2 };
VkRenderPassCreateInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.pAttachments = &attachmentDescs;
renderPassInfo.attachmentCount = 1;
renderPassInfo.subpassCount = 2;
renderPassInfo.pSubpasses = subpasses;
renderPassInfo.dependencyCount = 1;
renderPassInfo.pDependencies = &dependency;
vkUtils::checkResult(vkCreateRenderPass(_context->device, &renderPassInfo, nullptr, &_renderPass));
I have a dependency between the first and the second subpass. The specification says:
If an attachment specifies the
VK_ATTACHMENT_LOAD_OP_CLEAR
load operation, then it will logically be cleared at the start of the first subpass where it is used.
It will only be cleared at the start of the first subpass the attachment is used. And because there is a dependency between them, it should not be cleared in the second subpass.
The first use of an attachment must not specify a layout equal to VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL or VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL if the attachment specifies that the > loadOp is VK_ATTACHMENT_LOAD_OP_CLEAR. [...]
I get this error from the validation layer:
Cannot clear attachment 0 with invalid first layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
But the VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
layout is in the second subpass, not the first one?
It seems to be a bug in the layers, which simply do not check which usage is first (It was probably introduced in 1.0.17 SDK - 1.0.13 should not report this...): https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/sdk-1.0.17/layers/core_validation.cpp#L8557
spec quote:
The first use of an attachment must not specify a layout equal to
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
orVK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
if the attachment specifies that theloadOp
isVK_ATTACHMENT_LOAD_OP_CLEAR
. [...]
来源:https://stackoverflow.com/questions/38445001/layout-transition-between-multiple-subpasses-in-vulkan