【问题标题】:Graphics to graphics depth dependency, depth buffer is being corrupted图形到图形深度依赖性,深度缓冲区被破坏
【发布时间】:2020-06-20 04:43:01
【问题描述】:

我正在尝试执行以下操作: 取渲染通道 1,渲染到附件集 S。

进行渲染通道2,再次渲染到附件集S。

如何在官方Khronos github:中有一对一的解释

在图形到图形依赖项下。 但是,尝试实现与示例中相同的代码是行不通的。

这是我看到的:

这是我应该看到的:

我认为目前正在发生的事情是深度缓冲区未正确同步,因此深度测试无法正常工作。 我像这样创建两个渲染通道:

    // Create a render pass from the information of a render target
vk::UniqueRenderPass CreateRenderPass(HardwareInterface& hi,
    const std::vector<vk::AttachmentDescription>& attachment_descriptions)
{
    auto instance    = hi.GetInstance();
    auto phys_device = hi.GetPhysicalDevice();
    auto device      = hi.GetDevice();

    // Create a reference for each image target the renderpass will render to
    std::vector<vk::AttachmentReference> attachment_references(
        attachment_descriptions.size());
    for(uint i = 0; i < attachment_descriptions.size() - 1; i++)
    {
        vk::AttachmentReference color_attachment_ref(
            i, vk::ImageLayout::eColorAttachmentOptimal);
        attachment_references[i] = color_attachment_ref;
    }
    // Last attachment is depth
    vk::AttachmentReference depth_attachment_ref(
        attachment_descriptions.size() - 1,
        vk::ImageLayout::eDepthStencilAttachmentOptimal);
    attachment_references[attachment_references.size() - 1] = depth_attachment_ref;

    const uint subpass_num = 1;
    vector<vk::SubpassDescription> subpasses(subpass_num);
    for(auto& sub_pass: subpasses)
    {
        // No input attachment (3rd and 4th parameters)
        sub_pass                         = vk::SubpassDescription();
        sub_pass.pipelineBindPoint       = vk::PipelineBindPoint::eGraphics;
        sub_pass.inputAttachmentCount    = 0;
        sub_pass.pInputAttachments       = nullptr;
        sub_pass.colorAttachmentCount    = attachment_references.size() - 1;
        sub_pass.pColorAttachments       = attachment_references.data();
        sub_pass.pResolveAttachments     = nullptr;
        sub_pass.pDepthStencilAttachment = &attachment_references.back();
    }
    vector<vk::SubpassDependency> dependencies(subpass_num);
    uint current_dependency = 0;
    for(auto& dependency: dependencies)
    {
        // Set the dependency of this subpass
        uint32_t prev = current_dependency == 0 ? (uint32_t)VK_SUBPASS_EXTERNAL
                                                : current_dependency - 1;
        uint32_t next = current_dependency;
        current_dependency++;

        // Execution and memory dependencies between subpasses
        dependency               = vk::SubpassDependency();
        dependency.srcSubpass    = prev;
        dependency.dstSubpass    = next;
        dependency.srcStageMask  =
            vk::PipelineStageFlagBits::eColorAttachmentOutput
            | vk::PipelineStageFlagBits::eEarlyFragmentTests
            | vk::PipelineStageFlagBits::eLateFragmentTests;
        dependency.dstStageMask  =
            vk::PipelineStageFlagBits::eColorAttachmentOutput
            | vk::PipelineStageFlagBits::eEarlyFragmentTests
            | vk::PipelineStageFlagBits::eLateFragmentTests;
        dependency.srcAccessMask =
            vk::AccessFlagBits::eDepthStencilAttachmentWrite |
            vk::AccessFlagBits::eDepthStencilAttachmentRead;
        dependency.dstAccessMask =
            vk::AccessFlagBits::eColorAttachmentRead |
            vk::AccessFlagBits::eColorAttachmentWrite |
            vk::AccessFlagBits::eDepthStencilAttachmentRead |
            vk::AccessFlagBits::eDepthStencilAttachmentWrite;
    }

    vk::RenderPassCreateInfo render_pass_info(
        {},
        attachment_descriptions.size(),
        attachment_descriptions.data(),
        subpasses.size(),
        subpasses.data(),
        dependencies.size(),
        dependencies.data());

    auto [result, render_pass] = device.createRenderPassUnique(render_pass_info);
    if(result != vk::Result::eSuccess)
        Log::RecordLogError("Failed to create render pass!");

    return move(render_pass);
}

我已经阅读并重新阅读了该示例,并尝试使我的代码尽可能与它相同,但遗憾的是,问题仍然存在。 我创建工作图像的方式是让两个渲染发生在同一个渲染通道下,但我不想那样做。

【问题讨论】:

  • 请在问题文本中添加minimal reproducible example,而不是作为外部链接
  • 你的loadOp 和storeOp 两个pass中的附件是什么?
  • solidpixel storeOp 是 eDontCare,你是对的

标签: c++ vulkan depth-buffer depth-testing


【解决方案1】:

问题的产生是因为当我创建附件描述符时,我将渲染通道的storeOp 和loadOp 枚举设置为eDontCare,所以深度缓冲区对我来说是UB。

正如@solidpixel 在 cmets 中所建议的那样。解决方案是制作第一个eStore 和第二个'eLoad'。

【讨论】:

    猜你喜欢
    • 2013-01-08
    • 1970-01-01
    • 2018-05-27
    • 2015-09-08
    • 2016-09-01
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多