Vulkan中多个子通道之间的布局转换

时间:2016-07-18 19:56:59

标签: graphics 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));

我在第一个和第二个子通道之间存在依赖关系。规范说:

  

如果附件指定VK_ATTACHMENT_LOAD_OP_CLEAR加载   操作,然后它将在第一个开始时被逻辑清除   使用它的子通道。

只有在使用附件的第一个子通道开始时才会清除它。并且因为它们之间存在依赖关系,所以不应该在第二个子通道中清除它。

  

首次使用附件时,不得指定等于的布局   VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL或   如果附件指定,则为VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL   那个> loadOp是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 :(得分:3)

它似乎是图层中的一个错误,它根本不检查哪个用法是第一个(它可能是在1.0.17 SDK中引入的 - 1.0.13不应该报告这个......): https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/sdk-1.0.17/layers/core_validation.cpp#L8557

规格引用:

  

如果附件指定VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMALVK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,首次使用附件必须指定等于loadOpVK_ATTACHMENT_LOAD_OP_CLEAR的布局}。 [...]