图形到图形的深度依赖性,深度缓冲区已损坏
Graphics to graphics depth dependency, depth buffer is being corrupted
我正在尝试执行以下操作:
采用渲染通道 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);
}
我已经阅读并重读了该示例,并尝试使我的代码尽可能与它相同,但是问题仍然存在。
我创建工作图像的方式是在同一个渲染通道下进行两个渲染,但我不想那样做。
问题是因为当我创建附件描述符时,我将 renderpass 的 storeOp
和 loadOp
枚举设置为 eDontCare
所以深度缓冲区对我来说是 UB .
正如@solidpixel 在评论中所建议的那样。解决办法是让第一个eStore
和第二个'eLoad'.
我正在尝试执行以下操作: 采用渲染通道 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);
}
我已经阅读并重读了该示例,并尝试使我的代码尽可能与它相同,但是问题仍然存在。 我创建工作图像的方式是在同一个渲染通道下进行两个渲染,但我不想那样做。
问题是因为当我创建附件描述符时,我将 renderpass 的 storeOp
和 loadOp
枚举设置为 eDontCare
所以深度缓冲区对我来说是 UB .
正如@solidpixel 在评论中所建议的那样。解决办法是让第一个eStore
和第二个'eLoad'.