Seperate Framebuffer and Swapchain creation and fix gbuffer resource overallocation

This commit is contained in:
2024-07-10 07:50:48 -04:00
parent 6539525333
commit df65e4df49
18 changed files with 518 additions and 262 deletions

View File

@@ -31,7 +31,7 @@ namespace fgl::engine
};
{
a.resources()
} -> std::same_as< AttachmentResources >;
} -> std::same_as< AttachmentResources& >;
{
a.m_clear_value
} -> std::same_as< vk::ClearValue& >;

View File

@@ -24,7 +24,11 @@ namespace fgl::engine
void drawImGui() override;
std::string_view name() const override {}
std::string_view name() const override
{
//TODO: Get name of component
return "TEST NAME";
}
virtual ~ModelComponent() override {}

View File

@@ -139,6 +139,7 @@ namespace fgl::engine::gui
current = Composite;
}
/*
info.swap_chain.g_buffer_albedo_img->drawImGui( { v_size, h_size } );
ImGui::SameLine();
if ( ImGui::Selectable( options[ Albedo ], current == Albedo ) )
@@ -162,14 +163,17 @@ namespace fgl::engine::gui
log::debug( "Changing output to Position" );
current = Position;
}
*/
ImGui::EndCombo();
}
/*
switch ( current )
{
default:
[[fallthrough]];
case Composite:
info.swap_chain.g_buffer_composite_img->drawImGui();
break;
@@ -182,7 +186,7 @@ namespace fgl::engine::gui
case Position:
info.swap_chain.g_buffer_position_img->drawImGui();
break;
}
}*/
handleDragDrop( info );

View File

@@ -52,9 +52,9 @@ namespace fgl::engine
return info;
}
vk::raii::ImageView& ImageView::getVkView()
vk::ImageView ImageView::getVkView()
{
return m_image_view;
return *m_image_view;
}
vk::Extent2D ImageView::getExtent() const

View File

@@ -31,34 +31,25 @@ namespace fgl::engine
ImageView() = delete;
ImageView( std::shared_ptr< ImageHandle >& img );
ImageView( const ImageView& ) = delete;
ImageView& operator=( const ImageView& ) = delete;
ImageView( ImageView&& other ) noexcept :
m_resource( std::move( other.m_resource ) ),
m_descriptor_info( std::move( other.m_descriptor_info ) ),
m_image_view( std::move( other.m_image_view ) ),
m_sampler(
vk::Filter::eLinear,
vk::Filter::eLinear,
vk::SamplerMipmapMode::eLinear,
vk::SamplerAddressMode::eClampToEdge )
{
other.m_image_view = VK_NULL_HANDLE;
}
ImageView( ImageView&& other ) = default;
ImageView& operator=( ImageView&& other ) = default;
vk::raii::ImageView createImageView( const std::shared_ptr< ImageHandle >& img );
ImageView( std::shared_ptr< ImageHandle >& img );
[[nodiscard]] static vk::raii::ImageView createImageView( const std::shared_ptr< ImageHandle >& img );
vk::Extent2D getExtent() const;
[[nodiscard]] vk::Extent2D getExtent() const;
vk::raii::ImageView& getVkView();
[[nodiscard]] vk::ImageView getVkView();
VkImageView operator*() { return *m_image_view; }
[[nodiscard]] VkImageView operator*() { return *m_image_view; }
VkImage getVkImage() { return m_resource->getVkImage(); }
[[nodiscard]] VkImage getVkImage() { return m_resource->getVkImage(); }
Sampler& getSampler() { return m_sampler; };
[[nodiscard]] Sampler& getSampler() { return m_sampler; };
vk::DescriptorImageInfo descriptorInfo( vk::Sampler sampler, vk::ImageLayout layout ) const;
vk::DescriptorImageInfo descriptorInfo( vk::ImageLayout layout ) const;

View File

@@ -61,10 +61,7 @@ namespace fgl::engine
Sampler( Sampler&& other );
Sampler& operator=( Sampler&& );
~Sampler()
{
if ( *m_sampler != VK_NULL_HANDLE ) log::debug( "Sampler destroyed" );
}
~Sampler() {}
vk::raii::Sampler& getVkSampler() { return m_sampler; }

View File

@@ -66,7 +66,7 @@ namespace fgl::engine
OrientedBoundingBox< CoordinateSpace::Model > m_bounding_box;
PrimitiveMode m_mode;
PrimitiveTextures m_textures {};
PrimitiveTextures m_textures;
std::optional< TransformComponent > m_transform;
@@ -81,7 +81,9 @@ namespace fgl::engine
m_vertex_buffer( std::move( vertex_buffer ) ),
m_index_buffer( std::move( index_buffer ) ),
m_bounding_box( bounding_box ),
m_mode( mode )
m_mode( mode ),
m_textures(),
m_transform()
{}
Primitive(
@@ -94,7 +96,8 @@ namespace fgl::engine
m_index_buffer( std::move( index_buffer ) ),
m_bounding_box( bounding_box ),
m_mode( mode ),
m_textures( std::forward< decltype( m_textures ) >( textures ) )
m_textures( std::forward< decltype( m_textures ) >( textures ) ),
m_transform()
{}
Primitive() = delete;

View File

@@ -13,7 +13,8 @@
#include "engine/concepts/is_attachment.hpp"
#include "engine/image/Image.hpp"
#include "engine/rendering/Device.hpp"
#include "engine/image/ImageView.hpp"
#include "types.hpp"
namespace fgl::engine
{
@@ -33,7 +34,7 @@ namespace fgl::engine
class Attachment
{
vk::AttachmentDescription description {};
std::uint32_t index { std::numeric_limits< std::uint32_t >::max() };
std::uint32_t m_index { std::numeric_limits< std::uint32_t >::max() };
public:
@@ -43,9 +44,22 @@ namespace fgl::engine
void setClear( vk::ClearDepthStencilValue value ) { m_clear_value = value; }
//! Fills out with the resource image view for the given frame index
void fillVec( const std::uint16_t frame_idx, std::vector< vk::ImageView >& out )
{
auto& resource { m_attachment_resources.m_image_views.at( frame_idx ) };
assert( resource );
assert( out.size() > m_index );
vk::ImageView view { resource->getVkView() };
out.at( m_index ) = view;
}
AttachmentResources m_attachment_resources {};
void setIndex( const std::uint32_t idx ) { index = idx; }
void setIndex( const std::uint32_t idx ) { m_index = idx; }
constexpr static vk::AttachmentLoadOp loadOp = load_op;
constexpr static vk::AttachmentStoreOp storeOp = store_op;
@@ -80,6 +94,8 @@ namespace fgl::engine
{
linkImage( i, images[ i ] );
}
log::info( "Linked {} images to the swapchain color", images.size() );
}
void createResources( const std::uint32_t count, vk::Extent2D extent )
@@ -98,36 +114,55 @@ namespace fgl::engine
}
}
//! Creates a resource that is used across all frames
//! Creates resources required for this attachment
void createResourceSpread(
const std::uint32_t count, vk::Extent2D extent, vk::ImageUsageFlags extra_flags = vk::ImageUsageFlags( 0 ) )
{
auto image { std::make_shared< Image >(
extent,
description.format,
usage | vk::ImageUsageFlagBits::eInputAttachment | extra_flags,
inital_layout,
final_layout ) };
for ( std::uint32_t i = 0; i < count; ++i )
{
auto image { std::make_shared< Image >(
extent,
description.format,
usage | vk::ImageUsageFlagBits::eInputAttachment | extra_flags,
inital_layout,
final_layout ) };
m_attachment_resources.m_images.emplace_back( image );
m_attachment_resources.m_image_views.emplace_back( image->getView() );
}
}
AttachmentResources resources() { return m_attachment_resources; }
AttachmentResources& resources() { return m_attachment_resources; }
vk::AttachmentDescription& desc() { return description; }
std::uint32_t getIndex() const
{
assert(
index != std::numeric_limits< std::uint32_t >::max()
m_index != std::numeric_limits< std::uint32_t >::max()
&& "Attachment must be registered in RenderPass before use" );
return index;
return m_index;
}
friend class RenderPass;
ImageView& view( const FrameIndex index ) { return *m_attachment_resources.m_image_views[ index ]; }
Image& image( const FrameIndex index ) { return *m_attachment_resources.m_images[ index ]; }
void setName( const std::string str )
{
auto& images { m_attachment_resources.m_images };
auto& image_views { m_attachment_resources.m_image_views };
assert( images.size() == image_views.size() );
for ( std::size_t i = 0; i < images.size(); ++i )
{
images[ i ]->setName( str );
image_views[ i ]->setName( str );
}
}
friend class RenderPassBuilder;
};
template < is_attachment AttachmentT, vk::ImageLayout layout >

View File

@@ -0,0 +1,107 @@
//
// Created by kj16609 on 7/10/24.
//
#include "CameraSwapchain.hpp"
#include "Device.hpp"
#include "RenderPassBuilder.hpp"
/*
namespace fgl::engine
{
vk::Format pickOptimalDepthFormat()
{
return Device::getInstance().findSupportedFormat(
{ vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint },
vk::ImageTiling::eOptimal,
vk::FormatFeatureFlagBits::eDepthStencilAttachment );
}
std::vector< vk::raii::Framebuffer > CameraSwapchain::createFramebuffers()
{}
vk::raii::RenderPass CameraSwapchain::createRenderpass()
{
//In order to make the renderpass we need to know what we are doing.
RenderPassBuilder render_pass_builder;
//We start by defining the various attachments used here.
auto& [ color_attachment, depth_attachment, position_attachment, normal_attachment, albedo_attachment ] =
m_attachments;
render_pass_builder.registerAttachments(
color_attachment, depth_attachment, position_attachment, normal_attachment, albedo_attachment );
//TODO: Pre depth pass in order to reduce the number of fragment invocations
Subpass<
vk::PipelineBindPoint::eGraphics,
UsedAttachment< DepthAttachment, vk::ImageLayout::eDepthStencilAttachmentOptimal >,
UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal >,
UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal >,
UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal > >
g_buffer_subpass { 0, depth_attachment, position_attachment, normal_attachment, albedo_attachment };
g_buffer_subpass.registerDependencyFromExternal(
vk::AccessFlagBits::eDepthStencilAttachmentWrite,
vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests );
g_buffer_subpass.registerDependencyFromExternal(
vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput );
Subpass<
vk::PipelineBindPoint::eGraphics,
UsedAttachment< DepthAttachment, vk::ImageLayout::eDepthStencilAttachmentOptimal >,
UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal >,
InputAttachment< ColorAttachment, vk::ImageLayout::eShaderReadOnlyOptimal >,
InputAttachment< ColorAttachment, vk::ImageLayout::eShaderReadOnlyOptimal >,
InputAttachment< ColorAttachment, vk::ImageLayout::eShaderReadOnlyOptimal > >
composite_subpass {
1, depth_attachment, color_attachment, position_attachment, normal_attachment, albedo_attachment
};
// For color attachments
composite_subpass.registerDependencyFrom(
g_buffer_subpass,
vk::AccessFlagBits::eColorAttachmentWrite,
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::AccessFlagBits::eInputAttachmentRead,
vk::PipelineStageFlagBits::eFragmentShader,
vk::DependencyFlagBits::eByRegion );
// For depth attachment
composite_subpass.registerDependencyFrom(
g_buffer_subpass,
vk::AccessFlagBits::eDepthStencilAttachmentWrite,
vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests,
vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite,
vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests,
vk::DependencyFlagBits::eByRegion );
composite_subpass.registerDependencyToExternal(
vk::AccessFlagBits::eColorAttachmentWrite,
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::AccessFlagBits::eInputAttachmentRead,
vk::PipelineStageFlagBits::eFragmentShader,
vk::DependencyFlagBits::eByRegion );
render_pass_builder.registerSubpass( g_buffer_subpass );
render_pass_builder.registerSubpass( composite_subpass );
return render_pass_builder.create();
}
CameraSwapchain::CameraSwapchain( PhysicalDevice& physical_device, vk::Extent2D starting_extent ) :
m_physical_device( physical_device ),
m_final_render_info( vk::Format::eR8G8B8A8Unorm, pickOptimalDepthFormat() ),
m_attachments( m_final_render_info.m_color_format, m_final_render_info.m_depth_format ),
m_extent( starting_extent ),
m_renderpass( createRenderpass() ),
m_framebuffers( createFramebuffers() )
{}
} // namespace fgl::engine
*/

View File

@@ -0,0 +1,66 @@
//
// Created by kj16609 on 7/10/24.
//
#pragma once
#include <vulkan/vulkan_raii.hpp>
#include <vulkan/vulkan_structs.hpp>
#include "Attachment.hpp"
/*
namespace fgl::engine
{
class PhysicalDevice;
vk::Format pickOptimalDepthFormat();
class CameraSwapchain
{
PhysicalDevice& m_physical_device;
//! Contains the information for the final color buffer
struct
{
vk::Format m_color_format;
vk::Format m_depth_format;
} m_final_render_info;
struct
{
// Final output (composite) attachments
ColorAttachment color_attachment;
DepthAttachment depth_attachment;
// GBuffer Attachments
ColorAttachment position_attachment { vk::Format::eR16G16B16A16Sfloat };
ColorAttachment normal_attachment { vk::Format::eR16G16B16A16Sfloat };
ColorAttachment albedo_attachment { vk::Format::eR8G8B8A8Unorm };
} m_attachments;
vk::Extent2D m_extent;
vk::raii::RenderPass m_renderpass;
//! Framebuffers used in each frame (index using frame_idx)
std::vector< vk::raii::Framebuffer > m_framebuffers;
struct
{
//! Triggered when the image is ready to be used again
std::vector< vk::raii::Semaphore > image_available;
//! Triggered when the frame is finished rendering
std::vector< vk::raii::Semaphore > render_finished;
} semaphores;
std::vector< vk::raii::Framebuffer > createFramebuffers();
vk::raii::RenderPass createRenderpass();
public:
CameraSwapchain( PhysicalDevice& physical_device, vk::Extent2D starting_extent );
};
} // namespace fgl::engine
*/

View File

@@ -2,14 +2,13 @@
// Created by kj16609 on 12/31/23.
//
#include "RenderPass.hpp"
#include "Device.hpp"
#include "RenderPassBuilder.hpp"
namespace fgl::engine
{
vk::raii::RenderPass RenderPass::create()
vk::raii::RenderPass RenderPassBuilder::create()
{
auto& device { Device::getInstance() };

View File

@@ -31,7 +31,7 @@ namespace fgl::engine
}
};
class RenderPass
class RenderPassBuilder
{
std::vector< vk::AttachmentDescription > attachment_descriptions {};
std::vector< vk::ClearValue > m_clear_values {};
@@ -67,10 +67,6 @@ namespace fgl::engine
attachment_descriptions.push_back( attachments.desc() ),
m_clear_values.push_back( attachments.m_clear_value ) ),
... );
m_attachment_resources.reserve( sizeof...( Attachments ) );
( ( m_attachment_resources.emplace_back( attachments.m_attachment_resources ) ), ... );
}
std::unique_ptr< RenderPassResources > resources( std::uint16_t frame_count )

View File

@@ -100,8 +100,8 @@ namespace fgl::engine
std::pair< vk::raii::CommandBuffer&, vk::raii::CommandBuffer& > Renderer::beginFrame()
{
assert( !is_frame_started && "Cannot begin frame while frame is already in progress" );
auto [ result, image_idx ] = m_swapchain->acquireNextImage();
current_image_idx = image_idx;
auto [ result, present_index ] = m_swapchain->acquireNextImage();
current_present_index = present_index;
if ( result == vk::Result::eErrorOutOfDateKHR )
{
@@ -123,7 +123,8 @@ namespace fgl::engine
command_buffer.begin( begin_info );
vk::CommandBufferInheritanceInfo inheritance_info {};
inheritance_info.framebuffer = this->getSwapChain().getFrameBuffer( current_image_idx );
inheritance_info.framebuffer =
this->getSwapChain().getFrameBuffer( current_frame_index, current_present_index );
inheritance_info.renderPass = this->getSwapChainRenderPass();
inheritance_info.subpass = 2;
@@ -148,7 +149,7 @@ namespace fgl::engine
command_buffer.end();
const auto result { m_swapchain->submitCommandBuffers( command_buffer, current_image_idx ) };
const auto result { m_swapchain->submitCommandBuffers( command_buffer, current_present_index ) };
if ( result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR
|| m_window.wasWindowResized() )
@@ -160,7 +161,8 @@ namespace fgl::engine
throw std::runtime_error( "Failed to submit commmand buffer" );
is_frame_started = false;
current_frame_idx = static_cast< std::uint16_t >( ( current_frame_idx + 1 ) % SwapChain::MAX_FRAMES_IN_FLIGHT );
current_frame_index =
static_cast< std::uint16_t >( ( current_frame_index + 1 ) % SwapChain::MAX_FRAMES_IN_FLIGHT );
}
void Renderer::setViewport( const vk::raii::CommandBuffer& buffer )
@@ -196,7 +198,7 @@ namespace fgl::engine
vk::RenderPassBeginInfo render_pass_info {};
render_pass_info.pNext = VK_NULL_HANDLE;
render_pass_info.renderPass = m_swapchain->getRenderPass();
render_pass_info.framebuffer = m_swapchain->getFrameBuffer( static_cast< int >( current_image_idx ) );
render_pass_info.framebuffer = m_swapchain->getFrameBuffer( current_frame_index, current_present_index );
render_pass_info.renderArea = { .offset = { 0, 0 }, .extent = m_swapchain->getSwapChainExtent() };
render_pass_info.clearValueCount = static_cast< std::uint32_t >( clear_values.size() );
render_pass_info.pClearValues = clear_values.data();

View File

@@ -32,8 +32,8 @@ namespace fgl::engine
std::optional< TracyVkCtx > m_tracy_ctx { std::nullopt };
uint32_t current_image_idx { std::numeric_limits< std::uint32_t >::max() };
std::uint16_t current_frame_idx { 0 };
PresentIndex current_present_index { std::numeric_limits< PresentIndex >::max() };
FrameIndex current_frame_index { 0 };
bool is_frame_started { false };
void createCommandBuffers();
@@ -54,7 +54,7 @@ namespace fgl::engine
std::uint16_t getFrameIndex() const
{
assert( is_frame_started && "Cannot get frame index while frame not in progress" );
return current_frame_idx;
return current_frame_index;
}
bool isFrameInProgress() const { return is_frame_started; }
@@ -62,10 +62,10 @@ namespace fgl::engine
vk::raii::CommandBuffer& getCurrentCommandbuffer()
{
assert( is_frame_started && "Cannot get command buffer while frame not in progress" );
return m_command_buffer[ current_frame_idx ];
return m_command_buffer[ current_frame_index ];
}
vk::raii::CommandBuffer& getCurrentGuiCommandBuffer() { return m_gui_command_buffer[ current_frame_idx ]; }
vk::raii::CommandBuffer& getCurrentGuiCommandBuffer() { return m_gui_command_buffer[ current_frame_index ]; }
TracyVkCtx getCurrentTracyCTX() const
{

View File

@@ -109,7 +109,7 @@ namespace fgl::engine
vk::SubpassDescription description() { return subpass_description; }
friend class RenderPass;
friend class RenderPassBuilder;
void registerDependency(
std::uint32_t src_subpass,
@@ -142,8 +142,7 @@ namespace fgl::engine
log::critical(
"Rendering pass using a full dependency. THIS IS MOST LIKELY NOT WHAT YOU WANT UNLESS DEBUGGING" );
constexpr vk::AccessFlags all_access { vk::AccessFlagBits::eMemoryWrite | vk::AccessFlagBits::eMemoryRead };
constexpr vk::PipelineStageFlags all_stages { vk::PipelineStageFlagBits::eAllCommands
| vk::PipelineStageFlagBits::eAllGraphics };
constexpr vk::PipelineStageFlags all_stages { vk::PipelineStageFlagBits::eAllGraphics };
registerDependencyFrom(
parent, all_access, all_stages, all_access, all_stages, vk::DependencyFlagBits::eByRegion );

View File

@@ -8,29 +8,46 @@
#include <stdexcept>
#include "Attachment.hpp"
#include "RenderPass.hpp"
#include "RenderPassBuilder.hpp"
#include "Subpass.hpp"
#include "engine/assets/TransferManager.hpp"
namespace fgl::engine
{
SwapChain::SwapChain( vk::Extent2D extent, PhysicalDevice& phy_device ) :
SwapChain::SwapChain( const vk::Extent2D extent, PhysicalDevice& phy_device ) :
m_phy_device( phy_device ),
windowExtent( extent )
m_swapchain_support( Device::getInstance().getSwapChainSupport() ),
m_surface_format( chooseSwapSurfaceFormat( m_swapchain_support.formats ) ),
m_swap_chain_format( m_surface_format.format ),
m_swap_chain_extent( chooseSwapExtent( m_swapchain_support.capabilities ) ),
windowExtent( extent ),
m_render_attachments( getSwapChainImageFormat(), findDepthFormat() )
{
init();
}
SwapChain::SwapChain( vk::Extent2D extent, std::shared_ptr< SwapChain > previous ) :
SwapChain::SwapChain( const vk::Extent2D extent, std::shared_ptr< SwapChain > previous ) :
m_phy_device( previous->m_phy_device ),
old_swap_chain( previous ),
m_swapchain_support( Device::getInstance().getSwapChainSupport() ),
m_surface_format( chooseSwapSurfaceFormat( m_swapchain_support.formats ) ),
m_swap_chain_format( m_surface_format.format ),
m_swap_chain_extent( chooseSwapExtent( m_swapchain_support.capabilities ) ),
windowExtent( extent ),
old_swap_chain( previous )
m_render_attachments( getSwapChainImageFormat(), findDepthFormat() )
{
init();
old_swap_chain.reset();
}
vk::raii::Framebuffer& SwapChain::getFrameBuffer( const FrameIndex frame_idx, const PresentIndex present_idx )
{
assert( present_idx < m_swap_chain_buffers.size() );
assert( frame_idx < SwapChain::MAX_FRAMES_IN_FLIGHT );
return m_swap_chain_buffers[ present_idx ][ frame_idx ];
}
void SwapChain::init()
{
createSwapChain();
@@ -43,7 +60,7 @@ namespace fgl::engine
{
ZoneScoped;
std::vector< vk::Fence > fences { inFlightFences[ currentFrame ] };
std::vector< vk::Fence > fences { in_flight_fences[ current_frame_index ] };
if ( Device::getInstance().device().waitForFences( fences, VK_TRUE, std::numeric_limits< uint64_t >::max() )
!= vk::Result::eSuccess )
@@ -51,19 +68,20 @@ namespace fgl::engine
auto result { swapChain.acquireNextImage(
std::numeric_limits< uint64_t >::max(),
imageAvailableSemaphores[ currentFrame ] // must be a not signaled semaphore
imageAvailableSemaphores[ current_frame_index ] // must be a not signaled semaphore
) };
return result;
}
vk::Result SwapChain::submitCommandBuffers( const vk::raii::CommandBuffer& buffers, std::uint32_t imageIndex )
vk::Result SwapChain::
submitCommandBuffers( const vk::raii::CommandBuffer& buffers, const PresentIndex current_present_index )
{
ZoneScoped;
imagesInFlight[ imageIndex ] = inFlightFences[ currentFrame ];
images_in_flight[ current_present_index ] = in_flight_fences[ current_frame_index ];
std::vector< vk::Fence > fences { imagesInFlight[ imageIndex ] };
std::vector< vk::Fence > fences { images_in_flight[ current_present_index ] };
if ( Device::getInstance().device().waitForFences( fences, VK_TRUE, std::numeric_limits< uint64_t >::max() )
!= vk::Result::eSuccess )
@@ -71,7 +89,7 @@ namespace fgl::engine
vk::SubmitInfo submitInfo {};
std::vector< vk::Semaphore > wait_sems { imageAvailableSemaphores[ currentFrame ],
std::vector< vk::Semaphore > wait_sems { imageAvailableSemaphores[ current_frame_index ],
memory::TransferManager::getInstance().getFinishedSem() };
std::vector< vk::PipelineStageFlags > wait_stages { vk::PipelineStageFlagBits::eColorAttachmentOutput,
@@ -83,14 +101,14 @@ namespace fgl::engine
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &( *buffers );
std::vector< vk::Semaphore > signaled_semaphores { renderFinishedSemaphores[ currentFrame ] };
std::vector< vk::Semaphore > signaled_semaphores { renderFinishedSemaphores[ current_frame_index ] };
submitInfo.setSignalSemaphores( signaled_semaphores );
Device::getInstance().device().resetFences( fences );
std::vector< vk::SubmitInfo > submit_infos { submitInfo };
Device::getInstance().graphicsQueue().submit( submitInfo, inFlightFences[ currentFrame ] );
Device::getInstance().graphicsQueue().submit( submitInfo, in_flight_fences[ current_frame_index ] );
vk::PresentInfoKHR presentInfo = {};
@@ -99,7 +117,7 @@ namespace fgl::engine
std::vector< vk::SwapchainKHR > swapchains { swapChain };
presentInfo.setSwapchains( swapchains );
std::array< std::uint32_t, 1 > indicies { { imageIndex } };
std::array< std::uint32_t, 1 > indicies { { current_present_index } };
presentInfo.setImageIndices( indicies );
if ( auto present_result = Device::getInstance().presentQueue().presentKHR( presentInfo );
@@ -110,7 +128,7 @@ namespace fgl::engine
throw std::runtime_error( "failed to present swap chain image!" );
}
currentFrame = ( currentFrame + 1 ) % MAX_FRAMES_IN_FLIGHT;
current_frame_index = ( current_frame_index + 1 ) % MAX_FRAMES_IN_FLIGHT;
return vk::Result::eSuccess;
}
@@ -118,26 +136,23 @@ namespace fgl::engine
void SwapChain::createSwapChain()
{
ZoneScoped;
SwapChainSupportDetails swapChainSupport { Device::getInstance().getSwapChainSupport() };
vk::SurfaceFormatKHR surfaceFormat { chooseSwapSurfaceFormat( swapChainSupport.formats ) };
vk::PresentModeKHR presentMode { chooseSwapPresentMode( swapChainSupport.presentModes ) };
vk::Extent2D extent { chooseSwapExtent( swapChainSupport.capabilities ) };
const vk::PresentModeKHR presentMode { chooseSwapPresentMode( m_swapchain_support.presentModes ) };
uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
if ( swapChainSupport.capabilities.maxImageCount > 0
&& imageCount > swapChainSupport.capabilities.maxImageCount )
uint32_t imageCount = m_swapchain_support.capabilities.minImageCount + 1;
if ( m_swapchain_support.capabilities.maxImageCount > 0
&& imageCount > m_swapchain_support.capabilities.maxImageCount )
{
imageCount = swapChainSupport.capabilities.maxImageCount;
imageCount = m_swapchain_support.capabilities.maxImageCount;
}
vk::SwapchainCreateInfoKHR createInfo = {};
createInfo.surface = Device::getInstance().surface();
createInfo.minImageCount = imageCount;
createInfo.imageFormat = surfaceFormat.format;
createInfo.imageColorSpace = surfaceFormat.colorSpace;
createInfo.imageExtent = extent;
createInfo.imageFormat = m_surface_format.format;
createInfo.imageColorSpace = m_surface_format.colorSpace;
createInfo.imageExtent = m_swap_chain_extent;
createInfo.imageArrayLayers = 1;
createInfo.imageUsage = vk::ImageUsageFlagBits::eColorAttachment;
@@ -161,7 +176,7 @@ namespace fgl::engine
createInfo.pQueueFamilyIndices = nullptr; // Optional
}
createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
createInfo.preTransform = m_swapchain_support.capabilities.currentTransform;
createInfo.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque;
createInfo.presentMode = presentMode;
@@ -175,108 +190,25 @@ namespace fgl::engine
for ( std::uint64_t i = 0; i < swap_chain_images.size(); i++ )
{
auto& itter =
m_swap_chain_images
.emplace_back( extent, surfaceFormat.format, swap_chain_images[ i ], createInfo.imageUsage );
auto& itter = m_swap_chain_images.emplace_back(
m_swap_chain_extent, m_surface_format.format, swap_chain_images[ i ], createInfo.imageUsage );
itter.setName( "Swapchain image: " + std::to_string( i ) );
}
m_swap_chain_format = surfaceFormat.format;
m_swap_chain_extent = extent;
}
void SwapChain::createRenderPass()
{
ZoneScoped;
//Present attachment
ColoredPresentAttachment colorAttachment { getSwapChainImageFormat() };
for ( int i = 0; i < imageCount(); ++i )
{
auto& image { m_swap_chain_images[ i ] };
RenderPassBuilder render_pass_builder {};
image.setName( "SwapChainImage: " + std::to_string( i ) );
}
colorAttachment.linkImages( m_swap_chain_images );
// G-Buffer
ColorAttachment g_buffer_position { vk::Format::eR16G16B16A16Sfloat };
ColorAttachment g_buffer_normal { vk::Format::eR16G16B16A16Sfloat };
ColorAttachment g_buffer_albedo { vk::Format::eR8G8B8A8Unorm };
ColorAttachment g_buffer_composite { vk::Format::eR8G8B8A8Unorm };
g_buffer_position.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
g_buffer_normal.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
g_buffer_albedo.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
g_buffer_composite.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
g_buffer_position.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) );
g_buffer_normal.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) );
g_buffer_albedo.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) );
g_buffer_composite.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) );
g_buffer_position_img = std::make_unique< Texture >( g_buffer_position.m_attachment_resources.m_images[ 0 ]
->setName( "GBufferPosition" ) );
g_buffer_normal_img = std::make_unique< Texture >( g_buffer_normal.m_attachment_resources.m_images[ 0 ]
->setName( "GBufferNormal" ) );
g_buffer_albedo_img = std::make_unique< Texture >( g_buffer_albedo.m_attachment_resources.m_images[ 0 ]
->setName( "GBufferAlbedo" ) );
g_buffer_composite_img = std::make_unique< Texture >( g_buffer_composite.m_attachment_resources.m_images[ 0 ]
->setName( "GBufferComposite" ) );
RenderPass render_pass {};
DepthAttachment depthAttachment { findDepthFormat() };
depthAttachment.createResources( imageCount(), getSwapChainExtent() );
depthAttachment.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) );
render_pass.registerAttachments(
colorAttachment, depthAttachment, g_buffer_position, g_buffer_normal, g_buffer_albedo, g_buffer_composite );
for ( int i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
{
{
auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) };
set->setMaxIDX( 2 );
set->bindAttachment(
0,
*( g_buffer_position.resources().m_image_views[ i ].get() ),
vk::ImageLayout::eShaderReadOnlyOptimal );
set->bindAttachment(
1,
*( g_buffer_normal.resources().m_image_views[ i ].get() ),
vk::ImageLayout::eShaderReadOnlyOptimal );
set->bindAttachment(
2,
*( g_buffer_albedo.resources().m_image_views[ i ].get() ),
vk::ImageLayout::eShaderReadOnlyOptimal );
set->update();
m_gbuffer_descriptor_set[ i ] = std::move( set );
}
{
auto composite_set {
std::make_unique< descriptors::DescriptorSet >( GBufferCompositeDescriptorSet::createLayout() )
};
composite_set->setMaxIDX( 2 );
composite_set->bindAttachment(
0,
*( g_buffer_composite.resources().m_image_views[ 0 ].get() ),
vk::ImageLayout::eShaderReadOnlyOptimal );
composite_set->update();
m_gbuffer_composite_descriptor_set[ i ] = std::move( composite_set );
}
}
render_pass_builder.registerAttachments(
m_render_attachments.color,
m_render_attachments.depth,
m_gbuffer_attachments.position,
m_gbuffer_attachments.normal,
m_gbuffer_attachments.albedo,
m_gbuffer_attachments.composite );
static_assert( is_attachment< ColoredPresentAttachment > );
static_assert( is_attachment< DepthAttachment > );
@@ -287,7 +219,11 @@ namespace fgl::engine
UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal >,
UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal >,
UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal > >
g_buffer_subpass { 0, depthAttachment, g_buffer_position, g_buffer_normal, g_buffer_albedo };
g_buffer_subpass { 0,
m_render_attachments.depth,
m_gbuffer_attachments.position,
m_gbuffer_attachments.normal,
m_gbuffer_attachments.albedo };
g_buffer_subpass.registerDependencyFromExternal(
vk::AccessFlagBits::eDepthStencilAttachmentWrite,
@@ -299,17 +235,22 @@ namespace fgl::engine
Subpass<
vk::PipelineBindPoint::eGraphics,
UsedAttachment< DepthAttachment, vk::ImageLayout::eDepthStencilAttachmentOptimal >,
UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal >,
UsedAttachment< ColoredPresentAttachment, vk::ImageLayout::eColorAttachmentOptimal >,
InputAttachment< ColorAttachment, vk::ImageLayout::eShaderReadOnlyOptimal >,
InputAttachment< ColorAttachment, vk::ImageLayout::eShaderReadOnlyOptimal >,
InputAttachment< ColorAttachment, vk::ImageLayout::eShaderReadOnlyOptimal > >
composite_subpass {
1, depthAttachment, g_buffer_composite, g_buffer_position, g_buffer_normal, g_buffer_albedo
};
composite_subpass { 1,
m_render_attachments.depth,
m_render_attachments.color,
m_gbuffer_attachments.position,
m_gbuffer_attachments.normal,
m_gbuffer_attachments.albedo };
composite_subpass.registerDependencyFromExternal(
vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput );
composite_subpass.registerFullDependency( g_buffer_subpass );
// For color attachments
composite_subpass.registerDependencyFrom(
g_buffer_subpass,
@@ -328,23 +269,13 @@ namespace fgl::engine
vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests,
vk::DependencyFlagBits::eByRegion );
/*
composite_subpass.registerDependencyFrom(
g_buffer_subpass,
vk::AccessFlagBits::eColorAttachmentWrite,
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::AccessFlagBits::eTransferWrite,
vk::PipelineStageFlagBits::eTopOfPipe,
vk::DependencyFlagBits::eByRegion );
*/
// To prevent the composite buffer from getting obliterated by the gui pass and so we can use it to render to the GUI in certian areas, We need to keep them seperate and the composite image to be unmodified.
Subpass<
vk::PipelineBindPoint::eGraphics,
UsedAttachment< DepthAttachment, vk::ImageLayout::eDepthStencilAttachmentOptimal >,
UsedAttachment< ColoredPresentAttachment, vk::ImageLayout::eColorAttachmentOptimal >,
InputAttachment< ColorAttachment, vk::ImageLayout::eShaderReadOnlyOptimal > >
gui_subpass { 2, depthAttachment, colorAttachment, g_buffer_composite };
gui_subpass { 2, m_render_attachments.depth, m_render_attachments.color, m_gbuffer_attachments.composite };
gui_subpass.registerDependencyFromExternal(
vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput );
@@ -361,9 +292,6 @@ namespace fgl::engine
vk::PipelineStageFlagBits::eFragmentShader,
vk::DependencyFlagBits::eByRegion );
//composite_subpass.registerFullDependency( g_buffer_subpass );
//gui_subpass.registerFullDependency( composite_subpass );
gui_subpass.registerDependencyFrom(
composite_subpass,
vk::AccessFlagBits::eColorAttachmentWrite,
@@ -379,36 +307,134 @@ namespace fgl::engine
vk::PipelineStageFlagBits::eBottomOfPipe,
vk::DependencyFlagBits::eByRegion );
render_pass.registerSubpass( g_buffer_subpass );
render_pass.registerSubpass( composite_subpass );
render_pass.registerSubpass( gui_subpass );
render_pass_builder.registerSubpass( g_buffer_subpass );
render_pass_builder.registerSubpass( composite_subpass );
render_pass_builder.registerSubpass( gui_subpass );
m_render_pass = render_pass.create();
m_render_pass = render_pass_builder.create();
}
m_render_pass_resources = render_pass.resources( imageCount() );
m_clear_values = render_pass.getClearValues();
template < is_attachment... Attachments >
std::vector< vk::ImageView > fillViewsFromAttachments( uint8_t frame_idx, Attachments&&... attachments )
{
std::vector< vk::ImageView > views {};
views.resize( sizeof...( Attachments ) );
( ( attachments.fillVec( frame_idx, views ) ), ... );
return views;
}
void SwapChain::createFramebuffers()
{
ZoneScoped;
// Render target resource management
for ( int i = 0; i < imageCount(); ++i )
{
auto& image { m_swap_chain_images[ i ] };
image.setName( "SwapChainImage: " + std::to_string( i ) );
}
m_render_attachments.color.linkImages( m_swap_chain_images );
m_render_attachments.depth.createResources( imageCount(), getSwapChainExtent() );
m_render_attachments.depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) );
// GBuffer resource management
m_gbuffer_attachments.position.createResourceSpread(
SwapChain::MAX_FRAMES_IN_FLIGHT, getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
m_gbuffer_attachments.normal.createResourceSpread(
SwapChain::MAX_FRAMES_IN_FLIGHT, getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
m_gbuffer_attachments.albedo.createResourceSpread(
SwapChain::MAX_FRAMES_IN_FLIGHT, getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
m_gbuffer_attachments.composite.createResourceSpread(
SwapChain::MAX_FRAMES_IN_FLIGHT, getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
m_gbuffer_attachments.position.setClear( vk::ClearColorValue( std::array< float, 4 > {
{ 0.0f, 0.0f, 0.0f, 0.0f } } ) );
m_gbuffer_attachments.normal.setClear( vk::ClearColorValue( std::array< float, 4 > {
{ 0.0f, 0.0f, 0.0f, 0.0f } } ) );
m_gbuffer_attachments.albedo.setClear( vk::ClearColorValue( std::array< float, 4 > {
{ 0.0f, 0.0f, 0.0f, 0.0f } } ) );
m_gbuffer_attachments.composite.setClear( vk::ClearColorValue( std::array< float, 4 > {
{ 0.0f, 0.0f, 0.0f, 0.0f } } ) );
populateAttachmentClearValues(
m_render_attachments.color,
m_render_attachments.depth,
m_gbuffer_attachments.position,
m_gbuffer_attachments.normal,
m_gbuffer_attachments.albedo,
m_gbuffer_attachments.composite );
for ( FrameIndex i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
{
auto gbuffer_set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) };
gbuffer_set->setMaxIDX( 2 );
gbuffer_set->bindAttachment(
0, m_gbuffer_attachments.position.view( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
gbuffer_set
->bindAttachment( 1, m_gbuffer_attachments.normal.view( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
gbuffer_set
->bindAttachment( 2, m_gbuffer_attachments.albedo.view( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
gbuffer_set->update();
m_gbuffer_descriptor_set.at( i ) = std::move( gbuffer_set );
auto composite_set {
std::make_unique< descriptors::DescriptorSet >( GBufferCompositeDescriptorSet::createLayout() )
};
composite_set->setMaxIDX( 0 );
composite_set->bindAttachment(
0, m_gbuffer_attachments.composite.view( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
composite_set->update();
m_gbuffer_composite_descriptor_set.at( i ) = std::move( composite_set );
}
m_swap_chain_buffers.clear();
m_swap_chain_buffers.reserve( imageCount() );
for ( uint8_t i = 0; i < imageCount(); i++ )
for ( std::uint16_t present_idx = 0; present_idx < imageCount(); ++present_idx )
{
std::vector< vk::ImageView > attachments { m_render_pass_resources->forFrame( i ) };
std::vector< vk::raii::Framebuffer > temp {};
temp.reserve( SwapChain::MAX_FRAMES_IN_FLIGHT );
//Fill attachments for this frame
const vk::Extent2D swapChainExtent { getSwapChainExtent() };
vk::FramebufferCreateInfo framebufferInfo {};
framebufferInfo.renderPass = m_render_pass;
framebufferInfo.attachmentCount = static_cast< uint32_t >( attachments.size() );
framebufferInfo.pAttachments = attachments.data();
framebufferInfo.width = swapChainExtent.width;
framebufferInfo.height = swapChainExtent.height;
framebufferInfo.layers = 1;
for ( FrameIndex frame_idx = 0; frame_idx < SwapChain::MAX_FRAMES_IN_FLIGHT; frame_idx++ )
{
std::vector< vk::ImageView > attachments {};
m_swap_chain_buffers.push_back( Device::getInstance()->createFramebuffer( framebufferInfo ) );
attachments.emplace_back( *m_render_attachments.color.view( present_idx ) );
attachments.emplace_back( *m_render_attachments.depth.view( present_idx ) );
attachments.emplace_back( *m_gbuffer_attachments.position.view( frame_idx ) );
attachments.emplace_back( *m_gbuffer_attachments.normal.view( frame_idx ) );
attachments.emplace_back( *m_gbuffer_attachments.albedo.view( frame_idx ) );
attachments.emplace_back( *m_gbuffer_attachments.composite.view( frame_idx ) );
//Fill attachments for this frame
const vk::Extent2D swapchain_extent { getSwapChainExtent() };
vk::FramebufferCreateInfo framebufferInfo {};
framebufferInfo.renderPass = m_render_pass;
framebufferInfo.attachmentCount = static_cast< uint32_t >( attachments.size() );
framebufferInfo.pAttachments = attachments.data();
framebufferInfo.width = swapchain_extent.width;
framebufferInfo.height = swapchain_extent.height;
framebufferInfo.layers = 1;
temp.emplace_back( Device::getInstance()->createFramebuffer( framebufferInfo ) );
}
m_swap_chain_buffers.emplace_back( std::move( temp ) );
}
}
@@ -417,8 +443,8 @@ namespace fgl::engine
ZoneScoped;
imageAvailableSemaphores.reserve( MAX_FRAMES_IN_FLIGHT );
renderFinishedSemaphores.reserve( MAX_FRAMES_IN_FLIGHT );
inFlightFences.reserve( MAX_FRAMES_IN_FLIGHT );
imagesInFlight.resize( imageCount(), VK_NULL_HANDLE );
in_flight_fences.reserve( MAX_FRAMES_IN_FLIGHT );
images_in_flight.resize( imageCount(), VK_NULL_HANDLE );
vk::SemaphoreCreateInfo semaphoreInfo {};
@@ -431,31 +457,30 @@ namespace fgl::engine
imageAvailableSemaphores.push_back( device->createSemaphore( semaphoreInfo ) );
renderFinishedSemaphores.push_back( device->createSemaphore( semaphoreInfo ) );
inFlightFences.push_back( device->createFence( fenceInfo ) );
in_flight_fences.push_back( device->createFence( fenceInfo ) );
}
}
vk::SurfaceFormatKHR SwapChain::chooseSwapSurfaceFormat( const std::vector< vk::SurfaceFormatKHR >&
availableFormats )
available_formats )
{
ZoneScoped;
for ( const auto& availableFormat : availableFormats )
for ( const auto& format : available_formats )
{
if ( availableFormat.format == vk::Format::eB8G8R8A8Srgb
&& availableFormat.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear )
if ( format.format == vk::Format::eB8G8R8A8Srgb && format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear )
{
return availableFormat;
return format;
}
}
return availableFormats[ 0 ];
return available_formats[ 0 ];
}
vk::PresentModeKHR SwapChain::chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >&
availablePresentModes )
available_present_modes )
{
ZoneScoped;
for ( const auto& availablePresentMode : availablePresentModes )
for ( const auto& availablePresentMode : available_present_modes )
{
switch ( availablePresentMode )
{
@@ -480,12 +505,12 @@ namespace fgl::engine
}
}
for ( const auto& availablePresentMode : availablePresentModes )
for ( const auto& present_mode_khr : available_present_modes )
{
if ( availablePresentMode == vk::PresentModeKHR::eMailbox )
if ( present_mode_khr == vk::PresentModeKHR::eMailbox )
{
std::cout << "Present mode: Mailbox: ACTIVE" << std::endl;
return availablePresentMode;
return present_mode_khr;
}
}

View File

@@ -6,8 +6,9 @@
#include <vector>
#include "Device.hpp"
#include "RenderPass.hpp"
#include "RenderPassBuilder.hpp"
#include "engine/FrameInfo.hpp"
#include "engine/rendering/types.hpp"
#include "engine/texture/Texture.hpp"
namespace fgl::engine
@@ -16,43 +17,51 @@ namespace fgl::engine
{
public:
static constexpr std::uint16_t MAX_FRAMES_IN_FLIGHT = 2;
static constexpr FrameIndex MAX_FRAMES_IN_FLIGHT { 2 };
private:
PhysicalDevice& m_phy_device;
std::shared_ptr< SwapChain > old_swap_chain {};
SwapChainSupportDetails m_swapchain_support;
vk::SurfaceFormatKHR m_surface_format;
vk::Format m_swap_chain_format { vk::Format::eUndefined };
vk::Format m_swap_chain_depth_format { findDepthFormat() };
vk::Extent2D m_swap_chain_extent { 0, 0 };
std::vector< vk::raii::Framebuffer > m_swap_chain_buffers {};
std::vector< std::vector< vk::raii::Framebuffer > > m_swap_chain_buffers {};
vk::raii::RenderPass m_render_pass { VK_NULL_HANDLE };
std::unique_ptr< RenderPassResources > m_render_pass_resources { nullptr };
std::vector< Image > m_swap_chain_images {};
vk::Extent2D windowExtent;
vk::raii::SwapchainKHR swapChain { VK_NULL_HANDLE };
std::shared_ptr< SwapChain > old_swap_chain {};
std::vector< vk::raii::Semaphore > imageAvailableSemaphores {};
std::vector< vk::raii::Semaphore > renderFinishedSemaphores {};
std::vector< vk::raii::Fence > inFlightFences {};
std::vector< vk::Fence > imagesInFlight {};
size_t currentFrame { 0 };
std::vector< vk::raii::Fence > in_flight_fences {};
std::vector< vk::Fence > images_in_flight {};
size_t current_frame_index { 0 };
std::vector< vk::ClearValue > m_clear_values {};
public:
//! Attachments for the final render target
struct
{
ColoredPresentAttachment color; // Present attachment
DepthAttachment depth;
} m_render_attachments;
std::unique_ptr< Texture > g_buffer_position_img { nullptr };
std::unique_ptr< Texture > g_buffer_normal_img { nullptr };
std::unique_ptr< Texture > g_buffer_albedo_img { nullptr };
std::unique_ptr< Texture > g_buffer_composite_img { nullptr };
private:
struct
{
ColorAttachment position { vk::Format::eR16G16B16A16Sfloat };
ColorAttachment normal { vk::Format::eR16G16B16A16Sfloat };
ColorAttachment albedo { vk::Format::eR8G8B8A8Unorm };
ColorAttachment composite { vk::Format::eR8G8B8A8Unorm };
} m_gbuffer_attachments {};
void init();
void createSwapChain();
@@ -60,9 +69,16 @@ namespace fgl::engine
void createFramebuffers();
void createSyncObjects();
template < is_attachment... Attachments >
void populateAttachmentClearValues( Attachments&... attachments )
{
m_clear_values.resize( sizeof...( Attachments ) );
( ( m_clear_values[ attachments.getIndex() ] = attachments.m_clear_value ), ... );
}
// Helper functions
vk::SurfaceFormatKHR chooseSwapSurfaceFormat( const std::vector< vk::SurfaceFormatKHR >& availableFormats );
vk::PresentModeKHR chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >& availablePresentModes );
vk::SurfaceFormatKHR chooseSwapSurfaceFormat( const std::vector< vk::SurfaceFormatKHR >& available_formats );
vk::PresentModeKHR chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >& available_present_modes );
vk::Extent2D chooseSwapExtent( const vk::SurfaceCapabilitiesKHR& capabilities );
std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT >
@@ -97,16 +113,17 @@ namespace fgl::engine
SwapChain( const SwapChain& ) = delete;
SwapChain& operator=( const SwapChain& ) = delete;
vk::raii::Framebuffer& getFrameBuffer( std::uint32_t index )
{
return m_swap_chain_buffers[ static_cast< std::size_t >( index ) ];
}
vk::raii::Framebuffer& getFrameBuffer( const FrameIndex frame_index, const std::uint16_t present_idx );
vk::raii::RenderPass& getRenderPass() { return m_render_pass; }
std::uint16_t imageCount() const { return static_cast< std::uint16_t >( m_swap_chain_images.size() ); }
std::uint16_t imageCount() const { return m_swap_chain_images.size(); }
vk::Format getSwapChainImageFormat() const { return m_swap_chain_format; }
vk::Format getSwapChainImageFormat() const
{
assert( m_swap_chain_format != vk::Format::eUndefined );
return m_swap_chain_format;
}
vk::Extent2D getSwapChainExtent() const { return m_swap_chain_extent; }
@@ -130,7 +147,7 @@ namespace fgl::engine
[[nodiscard]] std::pair< vk::Result, std::uint32_t > acquireNextImage();
[[nodiscard]] vk::Result
submitCommandBuffers( const vk::raii::CommandBuffer& buffers, std::uint32_t imageIndex );
submitCommandBuffers( const vk::raii::CommandBuffer& buffers, PresentIndex current_present_index );
};
} // namespace fgl::engine

View File

@@ -0,0 +1,11 @@
//
// Created by kj16609 on 7/10/24.
//
#pragma once
namespace fgl::engine
{
using FrameIndex = std::uint16_t;
using PresentIndex = std::uint16_t;
} // namespace fgl::engine