为什么我的子通道输入附件布局无效?
Why is my subpass input attachment layout invalid?
我正在构建无头 Vulkan 渲染器,无法理解我收到的验证错误:
VUID-VkAttachmentReference-layout-parameter(ERROR / SPEC): msgNum: 1971405941 - Validation
Error: [ VUID-VkAttachmentReference-layout-parameter ] Object 0: handle = 0x7faea7064018, type =
VK_OBJECT_TYPE_DEVICE; | MessageID = 0x75814475 | vkCreateRenderPass: value of pCreateInfo-
>pSubpasses[0].pInputAttachments[1941].layout (3302454) does not fall within the begin..end
range of the core VkImageLayout enumeration tokens and is not an extension added token. The
Vulkan spec states: layout must be a valid VkImageLayout value
(https://vulkan.lunarg.com/doc/view/1.2.162.1/mac/1.2-extensions/vkspec.html#VUID-
VkAttachmentReference-layout-parameter)
Objects: 1
[0] 0x7faea7064018, type: 3, name: NULL
我已尽我所能,但我不明白问题出在哪里。我正在关注 this example which shows how to render headless and this 更一般的教程,即使我的代码与这两个示例几乎相同,也会导致 1941 年出现由分段错误引起的确切验证错误。
导致错误的函数代码:
void Renderer::CreateRenderPass(VkFormat depth_format) {
VkAttachmentDescription attachments[2];
attachments[0].format = VK_FORMAT_R8G8B8_UNORM;
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].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
attachments[1].format = depth_format;
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentReference color_ref;
color_ref.attachment = 0;
color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference depth_ref;
depth_ref.attachment = 1;
depth_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &color_ref;
subpass.pDepthStencilAttachment = &depth_ref;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
VkSubpassDependency dependencies[2];
dependencies[0].dstSubpass = 0;
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].srcSubpass = 0;
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkRenderPassCreateInfo render_pass_info;
render_pass_info.pNext = nullptr;
render_pass_info.subpassCount = 1;
render_pass_info.attachmentCount = 2;
render_pass_info.dependencyCount = 2;
render_pass_info.pSubpasses = &subpass;
render_pass_info.pAttachments = attachments;
render_pass_info.pDependencies = dependencies;
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
if (vkCreateRenderPass(device_, &render_pass_info, nullptr, &render_pass_))
throw std::runtime_error("failed to create render pass");
}
VkSubpassDescription subpass;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &color_ref;
subpass.pDepthStencilAttachment = &depth_ref;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
这里有几个成员未初始化。其中subpass.inputAttachmentCount
和subpass.pInputAttachments
。因此该数组包含垃圾,包括 layout
成员,它是 3302454
的值,是现有 VkImageLayout
枚举数的 none。
感谢@krOoze,我发现问题是我没有初始化很多subpass参数。但他确实提到你还需要将 subpass.pResolveAttachments 设置为空指针。
VkSubpassDescription subpass;
subpass.colorAttachmentCount = 1;
subpass.inputAttachmentCount = 0;
subpass.pInputAttachments = nullptr;
subpass.pResolveAttachments = nullptr;
subpass.pColorAttachments = &color_ref;
subpass.pDepthStencilAttachment = &depth_ref;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
我正在构建无头 Vulkan 渲染器,无法理解我收到的验证错误:
VUID-VkAttachmentReference-layout-parameter(ERROR / SPEC): msgNum: 1971405941 - Validation
Error: [ VUID-VkAttachmentReference-layout-parameter ] Object 0: handle = 0x7faea7064018, type =
VK_OBJECT_TYPE_DEVICE; | MessageID = 0x75814475 | vkCreateRenderPass: value of pCreateInfo-
>pSubpasses[0].pInputAttachments[1941].layout (3302454) does not fall within the begin..end
range of the core VkImageLayout enumeration tokens and is not an extension added token. The
Vulkan spec states: layout must be a valid VkImageLayout value
(https://vulkan.lunarg.com/doc/view/1.2.162.1/mac/1.2-extensions/vkspec.html#VUID-
VkAttachmentReference-layout-parameter)
Objects: 1
[0] 0x7faea7064018, type: 3, name: NULL
我已尽我所能,但我不明白问题出在哪里。我正在关注 this example which shows how to render headless and this 更一般的教程,即使我的代码与这两个示例几乎相同,也会导致 1941 年出现由分段错误引起的确切验证错误。
导致错误的函数代码:
void Renderer::CreateRenderPass(VkFormat depth_format) {
VkAttachmentDescription attachments[2];
attachments[0].format = VK_FORMAT_R8G8B8_UNORM;
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].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
attachments[1].format = depth_format;
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentReference color_ref;
color_ref.attachment = 0;
color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference depth_ref;
depth_ref.attachment = 1;
depth_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &color_ref;
subpass.pDepthStencilAttachment = &depth_ref;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
VkSubpassDependency dependencies[2];
dependencies[0].dstSubpass = 0;
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].srcSubpass = 0;
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkRenderPassCreateInfo render_pass_info;
render_pass_info.pNext = nullptr;
render_pass_info.subpassCount = 1;
render_pass_info.attachmentCount = 2;
render_pass_info.dependencyCount = 2;
render_pass_info.pSubpasses = &subpass;
render_pass_info.pAttachments = attachments;
render_pass_info.pDependencies = dependencies;
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
if (vkCreateRenderPass(device_, &render_pass_info, nullptr, &render_pass_))
throw std::runtime_error("failed to create render pass");
}
VkSubpassDescription subpass;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &color_ref;
subpass.pDepthStencilAttachment = &depth_ref;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
这里有几个成员未初始化。其中subpass.inputAttachmentCount
和subpass.pInputAttachments
。因此该数组包含垃圾,包括 layout
成员,它是 3302454
的值,是现有 VkImageLayout
枚举数的 none。
感谢@krOoze,我发现问题是我没有初始化很多subpass参数。但他确实提到你还需要将 subpass.pResolveAttachments 设置为空指针。
VkSubpassDescription subpass;
subpass.colorAttachmentCount = 1;
subpass.inputAttachmentCount = 0;
subpass.pInputAttachments = nullptr;
subpass.pResolveAttachments = nullptr;
subpass.pColorAttachments = &color_ref;
subpass.pDepthStencilAttachment = &depth_ref;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;