#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