Newer
Older
ForwardPlusRenderer / src / Buffer / DepthBuffer.cpp
#include <stdafx.h>
#define VULKAN_HPP_NO_EXCEPTIONS
#include "Buffer/DepthBuffer.h"
#include "Context.h"
#include "Device.h"
#include "SwapChain.h"
#include "Texture.h"
#include "Memory.h"
namespace fpr
{
vk::ImageTiling fpr::DepthBuffer::PREFERRED_IMAGE_TILING;

vk::Format fpr::DepthBuffer::QueryBestFormat(fpr::Device* device)
{
  //Iterate over wanted formats, ensure that they meet the required properties.
  for(const auto& format : DEPTH_BUFFER_IMAGE_FORMATS)
  {
    vk::FormatProperties format_properties = device->GetPhysicalDeviceHandle().getFormatProperties(format);

    bool optimal_flags_found = (format_properties.optimalTilingFeatures & REQUIRED_FEATURE_FLAGS) ==
        REQUIRED_FEATURE_FLAGS;
    if(PREFERRED_IMAGE_TILING == vk::ImageTiling::eOptimal && optimal_flags_found)
      return format;

    bool linear_flags_found = (format_properties.linearTilingFeatures & REQUIRED_FEATURE_FLAGS) ==
        REQUIRED_FEATURE_FLAGS;
    if(PREFERRED_IMAGE_TILING == vk::ImageTiling::eLinear && linear_flags_found)
      return format;
  }

  return vk::Format::eUndefined;
}


const vk::Image& DepthBuffer::GetDepthImage() const FPR_NOEXCEPT
{
  return m_depth_image.get();
}

const vk::DeviceMemory& DepthBuffer::GetDepthBufferMemory() const FPR_NOEXCEPT
{
  return m_depth_buffer_memory.get();
}

const vk::ImageView& DepthBuffer::GetDepthBufferView() const FPR_NOEXCEPT
{
  return m_depth_image_view.get();
}

const vk::Format& DepthBuffer::GetDepthImageFormat() const FPR_NOEXCEPT
{
  return m_depth_image_format;
}

DepthBuffer::DepthBuffer(fpr::Device* device, fpr::SwapChain* swapchain, vk::ImageTiling tiling)
{
  PREFERRED_IMAGE_TILING = tiling;
  m_depth_image_format   = QueryBestFormat(device);
  assert(("No supported depth buffer image format", m_depth_image_format != vk::Format::eUndefined));
  const vk::Extent3D extent(swapchain->GetCurrentExtent(), 1);

  vk::ImageCreateInfo depth_image_create_info{};

  depth_image_create_info.extent = extent;
  depth_image_create_info.format = m_depth_image_format;
  depth_image_create_info.usage  = vk::ImageUsageFlagBits::eDepthStencilAttachment | vk::ImageUsageFlagBits::eSampled; //Sampled in compute buffer
  depth_image_create_info.imageType     = vk::ImageType::e2D;
  depth_image_create_info.mipLevels     = 1;
  depth_image_create_info.arrayLayers   = 1;
  depth_image_create_info.initialLayout = vk::ImageLayout::eUndefined;

  auto [create_result, image] = device->GetLogicalDeviceHandle().createImageUnique(depth_image_create_info);

  m_depth_image = std::move(image);

  m_depth_buffer_memory = CreateImageMemory(device, *m_depth_image);

  m_depth_image_view = CreateImageView(
      device, *m_depth_image, m_depth_image_format, vk::ImageAspectFlagBits::eDepth, vk::ImageViewType::e2D);

}

vk::Format DepthBuffer::QueryBestImageFormat(
    const std::vector<vk::Format> possible_formats,
    vk::ImageTiling               tiling,
    vk::FormatFeatureFlags        required_flags)
{
  for(const auto& format : possible_formats)
  {
    vk::FormatProperties format_proprties =
        fpr::Context::Get().GetDevice()->GetPhysicalDeviceHandle().getFormatProperties(format);

    bool optimal_flags_found = (format_proprties.optimalTilingFeatures & required_flags) == required_flags;
    if(tiling == vk::ImageTiling::eOptimal && optimal_flags_found)
      return format;

    bool linear_flags_found = (format_proprties.linearTilingFeatures & required_flags) == required_flags;
    if(tiling == vk::ImageTiling::eLinear && linear_flags_found)
      return format;
  }
  return vk::Format::eUndefined;
}
} // namespace fpr