Layout transition between multiple subpasses in Vu

2019-05-08 18:46发布

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?

1条回答
迷人小祖宗
2楼-- · 2019-05-08 19:28

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 or VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL if the attachment specifies that the loadOp is VK_ATTACHMENT_LOAD_OP_CLEAR. [...]

查看更多
登录 后发表回答