Vulkan 中多个子通道之间的布局转换
Layout transition between multiple subpasses in Vulkan
我正在尝试做两个简单的子通道,其中第二个依赖于第一个。
//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));
我在第一个和第二个子通道之间存在依赖关系。规范说:
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.
它只会在附件使用的第一个子通道开始时被清除。并且因为它们之间存在依赖关系,所以不应该在第二个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. [...]
我从验证层得到这个错误:
Cannot clear attachment 0 with invalid first layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
但是VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
布局在第二个子通道,而不是第一个?
这似乎是图层中的一个错误,它根本不检查哪个用法是第一个(它可能是在 1.0.17 SDK 中引入的 - 1.0.13 不应该报告这个...):
https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/sdk-1.0.17/layers/core_validation.cpp#L8557
规格报价:
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
. [...]
我正在尝试做两个简单的子通道,其中第二个依赖于第一个。
//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));
我在第一个和第二个子通道之间存在依赖关系。规范说:
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.
它只会在附件使用的第一个子通道开始时被清除。并且因为它们之间存在依赖关系,所以不应该在第二个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. [...]
我从验证层得到这个错误:
Cannot clear attachment 0 with invalid first layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
但是VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
布局在第二个子通道,而不是第一个?
这似乎是图层中的一个错误,它根本不检查哪个用法是第一个(它可能是在 1.0.17 SDK 中引入的 - 1.0.13 不应该报告这个...): https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/sdk-1.0.17/layers/core_validation.cpp#L8557
规格报价:
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
. [...]