[英]Vulkan - Loading depth attachment in the second renderpass not working
我正在尝试将第一个渲染通道中的深度附件重用到第二个渲染通道中。 但是,它没有在第二个渲染过程中加载深度值。
//创建附件的代码
void VulkanRenderTarget::addAttachment(AttachmentCreateInfo createinfo)
{
auto device = mRenderer->getDevice();
Attachment attachment;
attachment.format = createinfo.format;
VkImageAspectFlags aspectMask = 0;
// Select aspect mask and layout depending on usage
// Color attachment
if (createinfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
{
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}
// Depth (and/or stencil) attachment
if (createinfo.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
{
if (attachment.hasDepth())
{
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
}
if (attachment.hasStencil())
{
aspectMask = aspectMask | VK_IMAGE_ASPECT_STENCIL_BIT;
}
}
assert(aspectMask > 0);
VkImageCreateInfo image = VulkanInitializers::imageCreateInfo();
image.imageType = VK_IMAGE_TYPE_2D;
image.format = createinfo.format;
image.extent.width = createinfo.width;
image.extent.height = createinfo.height;
image.extent.depth = 1;
image.mipLevels = 1;
image.arrayLayers = createinfo.layerCount;
image.samples = createinfo.imageSampleCount;
image.tiling = createinfo.tiling;
image.usage = createinfo.usage;
VkMemoryAllocateInfo memAlloc = VulkanInitializers::memoryAllocateInfo();
VkMemoryRequirements memReqs;
// Create image for this attachment
VERIFY(vkCreateImage(device, &image, nullptr, &attachment.image));
vkGetImageMemoryRequirements(device, attachment.image, &memReqs);
memAlloc.allocationSize = memReqs.size;
memAlloc.memoryTypeIndex = mRenderer->getMemoryType(memReqs.memoryTypeBits, createinfo.memoryFlag);
VERIFY(vkAllocateMemory(device, &memAlloc, nullptr, &attachment.memory));
VERIFY(vkBindImageMemory(device, attachment.image, attachment.memory, 0));
attachment.subresourceRange = {};
attachment.subresourceRange.aspectMask = aspectMask;
attachment.subresourceRange.levelCount = 1;
attachment.subresourceRange.layerCount = createinfo.layerCount;
VkImageViewCreateInfo imageView = VulkanInitializers::imageViewCreateInfo();
imageView.viewType = (createinfo.layerCount == 1) ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY;
imageView.format = createinfo.format;
imageView.subresourceRange = attachment.subresourceRange;
//todo: workaround for depth+stencil attachments
imageView.subresourceRange.aspectMask = (attachment.hasDepth()) ? VK_IMAGE_ASPECT_DEPTH_BIT : aspectMask;
imageView.image = attachment.image;
VERIFY(vkCreateImageView(device, &imageView, nullptr, &attachment.view));
// Fill attachment description
attachment.description = {};
attachment.description.samples = createinfo.imageSampleCount;
attachment.description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachment.description.storeOp = (createinfo.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachment.description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachment.description.format = createinfo.format;
attachment.description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
// Final layout
// If not, final layout depends on attachment type
if (attachment.hasDepth() || attachment.hasStencil())
{
attachment.description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
//attachment.description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
}
else
{
attachment.description.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
mAttachments.push_back(attachment);
}
///第一个渲染通道创建
// Four attachments (3 color, 1 depth)
AttachmentCreateInfo attachmentInfo = {};
attachmentInfo.width = mWidth;
attachmentInfo.height = mHeight;
attachmentInfo.layerCount = 1;
attachmentInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
attachmentInfo.imageSampleCount = mRenderer->getMSAAsamples();
// Color attachments
// Attachment 0: (World space) Positions
//attachmentInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
attachmentInfo.format = VK_FORMAT_R32G32B32A32_SFLOAT;
addAttachment(attachmentInfo);
// Attachment 1: (World space) Normals
attachmentInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
addAttachment(attachmentInfo);
// Attachment 2: Albedo (color)
attachmentInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
addAttachment(attachmentInfo);
//depth
attachmentInfo.format = mRenderer->getDepthFormat();
attachmentInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
addAttachment(attachmentInfo);
{
//create sampler
VkSamplerCreateInfo samplerInfo = VulkanInitializers::samplerCreateInfo();
samplerInfo.magFilter = VK_FILTER_NEAREST;
samplerInfo.minFilter = VK_FILTER_NEAREST;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerInfo.mipLodBias = 0.0f;
samplerInfo.maxAnisotropy = 1.0f;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = 1.0f;
samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
VERIFY(vkCreateSampler(device, &samplerInfo, nullptr, &sampler));
}
//create renderpass and frame buffer
{
std::vector<VkAttachmentDescription> attachmentDescriptions;
for (auto& attachment : mAttachments)
{
attachmentDescriptions.push_back(attachment.description);
};
// Collect attachment references
std::vector<VkAttachmentReference> colorReferences;
VkAttachmentReference depthReference = {};
bool hasDepth = false;
bool hasColor = false;
uint32_t attachmentIndex = 0;
for (auto& attachment : mAttachments)
{
if (attachment.isDepthStencil())
{
// Only one depth attachment allowed
assert(!hasDepth);
depthReference.attachment = attachmentIndex;
depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
hasDepth = true;
}
else
{
colorReferences.push_back({ attachmentIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL });
hasColor = true;
}
attachmentIndex++;
};
// Default render pass setup uses only one subpass
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
if (hasColor)
{
subpass.pColorAttachments = colorReferences.data();
subpass.colorAttachmentCount = static_cast<uint32_t>(colorReferences.size());
}
if (hasDepth)
{
subpass.pDepthStencilAttachment = &depthReference;
}
// Use subpass dependencies for attachment layout transitions
std::array<VkSubpassDependency, 2> dependencies;
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].dstSubpass = 0;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies[1].srcSubpass = 0;
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
// Create render pass
VkRenderPassCreateInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.pAttachments = attachmentDescriptions.data();
renderPassInfo.attachmentCount = static_cast<uint32_t>(attachmentDescriptions.size());
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass;
renderPassInfo.dependencyCount = static_cast<uint32_t>(dependencies.size());
renderPassInfo.pDependencies = dependencies.data();
VERIFY(vkCreateRenderPass(device, &renderPassInfo, nullptr, &mRenderPass));
std::vector<VkImageView> attachmentViews;
for (auto attachment : mAttachments)
{
attachmentViews.push_back(attachment.view);
}
// Find. max number of layers across attachments
uint32_t maxLayers = 0;
for (auto attachment : mAttachments)
{
if (attachment.subresourceRange.layerCount > maxLayers)
{
maxLayers = attachment.subresourceRange.layerCount;
}
}
VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = mRenderPass;
framebufferInfo.pAttachments = attachmentViews.data();
framebufferInfo.attachmentCount = static_cast<uint32_t>(attachmentViews.size());
framebufferInfo.width = mWidth;
framebufferInfo.height = mHeight;
framebufferInfo.layers = maxLayers;
mFrameBuffers.clear();
mFrameBuffers.resize(1);
VERIFY(vkCreateFramebuffer(device, &framebufferInfo, nullptr, &mFrameBuffers[0]));
}
///第二个渲染通道
finalImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
std::array<VkAttachmentDescription, 3> attachments = {};
// Multisampled attachment that we render to
attachments[0].format = mRenderer->getSCImageFormat();// swapChain.colorFormat;
attachments[0].samples = mRenderer->getMSAAsamples();// settings.sampleCount;
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
// This is the frame buffer attachment to where the multisampled image
// will be resolved to and which will be presented to the swapchain
attachments[1].format = mRenderer->getSCImageFormat();;
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[1].finalLayout = finalImageLayout;
// Multisampled depth attachment we render to
attachments[2].format = mRenderer->getDepthFormat();// depthFormat;
attachments[2].samples = mRenderer->getMSAAsamples();// settings.sampleCount;
attachments[2].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;// VK_ATTACHMENT_LOAD_OP_LOAD; //VK_ATTACHMENT_LOAD_OP_CLEAR; use depth from deferred renderer
attachments[2].storeOp = VK_ATTACHMENT_STORE_OP_STORE;// VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[2].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentReference colorReference = {};
colorReference.attachment = 0;
colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference depthReference = {};
depthReference.attachment = 2;
depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
// Resolve attachment reference for the color attachment
VkAttachmentReference resolveReference = {};
resolveReference.attachment = 1;
resolveReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorReference;
// Pass our resolve attachments to the sub pass
subpass.pResolveAttachments = &resolveReference;
subpass.pDepthStencilAttachment = &depthReference;
std::vector<VkSubpassDependency> dependencies;
dependencies.resize(2);
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].dstSubpass = 0;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; // Both stages might have access the depth-buffer, so need both in src/dstStageMask;;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies[1].srcSubpass = 0;
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_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].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
VkRenderPassCreateInfo renderPassCI = {};
renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassCI.attachmentCount = static_cast<uint32_t>(attachments.size());
renderPassCI.pAttachments = attachments.data();
renderPassCI.subpassCount = 1;
renderPassCI.pSubpasses = &subpass;
renderPassCI.dependencyCount = static_cast<uint32_t>(dependencies.size());
renderPassCI.pDependencies = dependencies.data();
VERIFY(vkCreateRenderPass(device, &renderPassCI, nullptr, &mRenderPass));
VkImageCreateInfo imageCI{};
imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCI.imageType = VK_IMAGE_TYPE_2D;
imageCI.format = mRenderer->getSCImageFormat();// swapChain.colorFormat;
imageCI.extent.width = mWidth;// width;
imageCI.extent.height = mHeight;
imageCI.extent.depth = 1;
imageCI.mipLevels = 1;
imageCI.arrayLayers = 1;
imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCI.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCI.samples = mRenderer->getMSAAsamples();// settings.sampleCount;
imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
VERIFY(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.color.image));
VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(device, multisampleTarget.color.image, &memReqs);
VkMemoryAllocateInfo memAllocInfo{};
memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memAllocInfo.allocationSize = memReqs.size;
VkBool32 lazyMemTypePresent;
memAllocInfo.memoryTypeIndex = mRenderer->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &lazyMemTypePresent);
if (!lazyMemTypePresent) {
memAllocInfo.memoryTypeIndex = mRenderer->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
}
VERIFY(vkAllocateMemory(device, &memAllocInfo, nullptr, &multisampleTarget.color.memory));
vkBindImageMemory(device, multisampleTarget.color.image, multisampleTarget.color.memory, 0);
// Create image view for the MSAA target
VkImageViewCreateInfo imageViewCI{};
imageViewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewCI.image = multisampleTarget.color.image;
imageViewCI.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewCI.format = mRenderer->getSCImageFormat();// swapChain.colorFormat;
imageViewCI.components.r = VK_COMPONENT_SWIZZLE_R;
imageViewCI.components.g = VK_COMPONENT_SWIZZLE_G;
imageViewCI.components.b = VK_COMPONENT_SWIZZLE_B;
imageViewCI.components.a = VK_COMPONENT_SWIZZLE_A;
imageViewCI.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageViewCI.subresourceRange.levelCount = 1;
imageViewCI.subresourceRange.layerCount = 1;
VERIFY(vkCreateImageView(device, &imageViewCI, nullptr, &multisampleTarget.color.view));
AttachmentCreateInfo attachmentInfo = {};
attachmentInfo.width = mWidth;
attachmentInfo.height = mHeight;
attachmentInfo.layerCount = 1;
attachmentInfo.imageSampleCount = mRenderer->getMSAAsamples();
attachmentInfo.format = mRenderer->getDepthFormat();
attachmentInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
addAttachment(attachmentInfo);
auto& depthAttachment = mAttachments.back();
multisampleTarget.depth.image = depthAttachment.image;
multisampleTarget.depth.view = depthAttachment.view;
multisampleTarget.depth.memory = depthAttachment.memory;
std::vector<VkImageView> attachments;
attachments.emplace_back(multisampleTarget.color.view);
attachments.emplace_back(color.view);
attachments.emplace_back(multisampleTarget.depth.view);
VkFramebufferCreateInfo frameBufferCI{};
frameBufferCI.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
frameBufferCI.pNext = NULL;
frameBufferCI.renderPass = mRenderPass;
frameBufferCI.attachmentCount = static_cast<uint32_t>(attachments.size());
frameBufferCI.pAttachments = attachments.data();
frameBufferCI.width = mWidth;
frameBufferCI.height = mHeight;
frameBufferCI.layers = 1;
mFrameBuffers.resize(1);
VERIFY(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &mFrameBuffers[0]));
在 renderDoc 中,我可以看到第二个渲染通道深度附件为“未定义的 img”
我猜我以正确的方式使用 Load 和 StoreOps 并且还创建了子通道依赖项,它负责将深度值从第一个渲染通道传输到第二个渲染通道。 但是:它不起作用。 .( 为我的新手编码风格道歉。大多数来自 SaschaWillems 示例。
在第二遍,深度附件描述中,它在未定义的 state 中“加载”图像:
attachments[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
根据您的附件创建代码,我认为它应该是VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.