I am following a series of beginner tutorials on vkguide(.)com+ vulkan-tutorial, but I am having major problems getting the depth buffer to work. I’ve scoured the code a number of times in their examples, and it seems to match exactly. The program runs and there are no validation errors, but the depth buffer appears to have no effect
To my understanding, the process is:
- Create the depth buffer info (and for this you need a VkImageCreateInfo and a VkImageViewCreateInfo), where the aspect is set to VK_IMAGE_ASPECT_DEPTH
- Allocate memory for the buffer (for this I use AMD’s VMA)
- Create the actual ImageView with a call to vkCreateImageView
- Link the buffer to the render pass
- Link it to the pipeline
- Set appropriate Clear color
- Render!
Here are the relevant code sections:
I use the vulkan.hpp header
Create and allocate the depth buffer
auto _depth_image_extent = vk::Extent3D(window_extent, 1);
_fmt_depth = vk::Format::eD32Sfloat;
auto depth_info = vk::ImageCreateInfo({}, vk::ImageType::e2D, _fmt_depth, _depth_image_extent, 1, 1, vk::SampleCountFlagBits::e1, vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eDepthStencilAttachment);VmaAllocationCreateInfo dimg_info{};
dimg_info.usage = VMA_MEMORY_USAGE_GPU_ONLY;
dimg_info.requiredFlags = static_cast(vk::MemoryPropertyFlagBits::eDeviceLocal);
auto res=vmaCreateImage(g_vma_allocator, reinterpret_cast<VkImageCreateInfo*>(&depth_info), &dimg_info, reinterpret_cast<VkImage*>(&_img_depth.image), &_img_depth.allocation, nullptr);SkCheck(static_castvk::Result(res));
_imgs_swapchain = vkb_swapchain->get_images().value();
_fmt_swapchain = vk::Format{ vkb_swapchain->image_format };
vk::ImageViewCreateInfo image_view_create_info({}, _img_depth.image,vk::ImageViewType::e2D, _fmt_depth, {}, vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1));
_img_view_depth = vk::raii::ImageView(*_device, image_view_create_info);
Link to render pass:
auto color_attachment = vk::AttachmentDescription({},_fmt_swapchain,vk::SampleCountFlagBits::e1,vk::AttachmentLoadOp::eClear,vk::AttachmentStoreOp::eStore,vk::AttachmentLoadOp::eDontCare,vk::AttachmentStoreOp::eDontCare,vk::ImageLayout::eUndefined,vk::ImageLayout::ePresentSrcKHR); auto attachment_ref_color = vk::AttachmentReference(0, vk::ImageLayout::eColorAttachmentOptimal); auto depth_attachment = vk::AttachmentDescription({}, _fmt_depth, vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilAttachmentOptimal); vk::AttachmentReference attachment_ref_depth(1, vk::ImageLayout::eDepthStencilAttachmentOptimal); auto sd = vk::SubpassDescription({}, vk::PipelineBindPoint::eGraphics, 0, {}, 1, &attachment_ref_color,{},&attachment_ref_depth); std::array attachment_descriptions{ color_attachment,depth_attachment }; std::array sds = { sd }; vk::SubpassDependency dependency(VK_SUBPASS_EXTERNAL, 0, vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests, vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests, vk::AccessFlagBits::eNoneKHR, vk::AccessFlagBits::eColorAttachmentWrite); auto rpci = vk::RenderPassCreateInfo({},attachment_descriptions,sds,dependency); _renderpass = std::make_unique<vk::raii::RenderPass>(*_device, rpci);
Add it to framebuffer
auto _window_extents = window::Glvk::get_framebuffer_size();
for(auto const &iv: _img_views_swapchain)
{
std::array attachments = { iv,_img_view_depth };
auto fb_info = vk::FramebufferCreateInfo({}, **_renderpass, attachments, _window_extents.width,_window_extents.height, 1);_framebuffers.push_back(vk::raii::Framebuffer(*_device, fb_info));
}
Add to pipeline
auto gpcio = vk::GraphicsPipelineCreateInfo({}, _shader_stages, &_vertex_input_state_create_info, &_input_assembly_state_create_info, {}, &viewport_state, &_rasterization_state_create_info, &_multisample_state_create_info, &depth_stencil_state, &pcbscio, {}, *_pipeline_layout, *pass, 0);
vk::raii::Pipeline pipeline(device, nullptr, gpcio);
Set clear in draw:
depth_clear.depthStencil = vk::ClearDepthStencilValue(1.0f, 0);
std::array clear_values = { color_clear,depth_clear };
…profit…
But sadly, nothing seems to happen! I’ve been stuck on this for a number of days now, and I’m hoping far more experienced eyes will be able diagnose (and offer solution) to this debacle.
Much appreciated.