From 21268f2d4df605a6c75f5fa76785aaa787abb8a3 Mon Sep 17 00:00:00 2001 From: kj16609 Date: Thu, 11 Jul 2024 01:32:57 -0400 Subject: [PATCH] Rework swapchain to no longer init inside of ctor body --- src/engine/concepts/is_attachment.hpp | 4 +- src/engine/rendering/Attachment.hpp | 9 +- src/engine/rendering/RenderPass.hpp | 103 -------- .../{RenderPass.cpp => RenderPassBuilder.cpp} | 5 +- src/engine/rendering/RenderPassBuilder.hpp | 52 ++++ src/engine/rendering/Subpass.hpp | 2 +- src/engine/rendering/SwapChain.cpp | 236 +++++++++--------- src/engine/rendering/SwapChain.hpp | 65 +++-- 8 files changed, 233 insertions(+), 243 deletions(-) delete mode 100644 src/engine/rendering/RenderPass.hpp rename src/engine/rendering/{RenderPass.cpp => RenderPassBuilder.cpp} (88%) create mode 100644 src/engine/rendering/RenderPassBuilder.hpp diff --git a/src/engine/concepts/is_attachment.hpp b/src/engine/concepts/is_attachment.hpp index 0c0d998..a8edbe6 100644 --- a/src/engine/concepts/is_attachment.hpp +++ b/src/engine/concepts/is_attachment.hpp @@ -30,8 +30,8 @@ namespace fgl::engine a.linkImage( std::declval< std::uint16_t >(), std::declval< Image& >() ) }; { - a.resources() - } -> std::same_as< AttachmentResources >; + a.getView( std::declval< std::uint8_t >() ) + } -> std::same_as< ImageView& >; { a.m_clear_value } -> std::same_as< vk::ClearValue& >; diff --git a/src/engine/rendering/Attachment.hpp b/src/engine/rendering/Attachment.hpp index 3588e94..b145c31 100644 --- a/src/engine/rendering/Attachment.hpp +++ b/src/engine/rendering/Attachment.hpp @@ -76,6 +76,7 @@ namespace fgl::engine void linkImages( std::vector< Image >& images ) { + assert( images.size() > 0 ); for ( std::uint16_t i = 0; i < images.size(); ++i ) { linkImage( i, images[ i ] ); @@ -115,7 +116,11 @@ namespace fgl::engine } } - AttachmentResources resources() { return m_attachment_resources; } + ImageView& getView( std::uint8_t frame_idx ) + { + assert( frame_idx < m_attachment_resources.m_image_views.size() ); + return *m_attachment_resources.m_image_views[ frame_idx ]; + } vk::AttachmentDescription& desc() { return description; } @@ -127,7 +132,7 @@ namespace fgl::engine return index; } - friend class RenderPass; + friend class RenderPassBuilder; }; template < is_attachment AttachmentT, vk::ImageLayout layout > diff --git a/src/engine/rendering/RenderPass.hpp b/src/engine/rendering/RenderPass.hpp deleted file mode 100644 index b60e802..0000000 --- a/src/engine/rendering/RenderPass.hpp +++ /dev/null @@ -1,103 +0,0 @@ -// -// Created by kj16609 on 12/30/23. -// - -#pragma once - -#include "Subpass.hpp" -#include "engine/image/ImageView.hpp" - -namespace fgl::engine -{ - - struct RenderPassResources - { - std::vector< std::vector< std::shared_ptr< ImageView > > > m_image_views; - - RenderPassResources() = delete; - RenderPassResources( const RenderPassResources& ) = delete; - - RenderPassResources( std::vector< std::vector< std::shared_ptr< ImageView > > >&& image_views ) : - m_image_views( std::move( image_views ) ) - {} - - std::vector< vk::ImageView > forFrame( std::uint32_t frame ) const - { - std::vector< vk::ImageView > views; - - for ( auto& view : m_image_views.at( frame ) ) views.push_back( view->getVkView() ); - - return views; - } - }; - - class RenderPass - { - std::vector< vk::AttachmentDescription > attachment_descriptions {}; - std::vector< vk::ClearValue > m_clear_values {}; - - std::vector< vk::SubpassDescription > subpass_descriptions {}; - std::vector< vk::SubpassDependency > dependencies {}; - - std::vector< AttachmentResources > m_attachment_resources {}; - - public: - - std::vector< vk::ClearValue > getClearValues() const { return m_clear_values; } - - template < typename SubpassT > - requires is_subpass< SubpassT > - void registerSubpass( SubpassT& subpass ) - { - subpass_descriptions.emplace_back( subpass.description() ); - - for ( auto& dependency : subpass.dependencies ) - { - dependencies.push_back( dependency ); - } - } - - template < is_attachment... Attachments > - void registerAttachments( Attachments&... attachments ) - { - attachment_descriptions.reserve( sizeof...( Attachments ) ); - m_clear_values.reserve( sizeof...( Attachments ) ); - - ( ( attachments.setIndex( static_cast< std::uint32_t >( attachment_descriptions.size() ) ), - 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 ) - { - assert( m_attachment_resources.size() > 0 && "Must register attachments before getting resources" ); - - //Each attachment will have a vector of image views, one for each frame - // We need to seperate them out so that we have a vector of image views for each frame - std::vector< std::vector< std::shared_ptr< ImageView > > > views; - - views.resize( frame_count ); - - for ( auto& attachment : m_attachment_resources ) - { - assert( - attachment.m_image_views.size() == frame_count - && "Attachment image views must be equal to frame count" ); - for ( std::uint16_t frame_idx = 0; frame_idx < attachment.m_image_views.size(); ++frame_idx ) - { - views[ frame_idx ].emplace_back( attachment.m_image_views[ frame_idx ] ); - } - } - - return std::make_unique< RenderPassResources >( std::move( views ) ); - } - - vk::raii::RenderPass create(); - }; - -} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/rendering/RenderPass.cpp b/src/engine/rendering/RenderPassBuilder.cpp similarity index 88% rename from src/engine/rendering/RenderPass.cpp rename to src/engine/rendering/RenderPassBuilder.cpp index 51bacb2..f1cde4b 100644 --- a/src/engine/rendering/RenderPass.cpp +++ b/src/engine/rendering/RenderPassBuilder.cpp @@ -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() }; diff --git a/src/engine/rendering/RenderPassBuilder.hpp b/src/engine/rendering/RenderPassBuilder.hpp new file mode 100644 index 0000000..a8aa15b --- /dev/null +++ b/src/engine/rendering/RenderPassBuilder.hpp @@ -0,0 +1,52 @@ +// +// Created by kj16609 on 12/30/23. +// + +#pragma once + +#include "Subpass.hpp" +#include "engine/image/ImageView.hpp" + +namespace fgl::engine +{ + + class RenderPassBuilder + { + std::vector< vk::AttachmentDescription > attachment_descriptions {}; + std::vector< vk::ClearValue > m_clear_values {}; + + std::vector< vk::SubpassDescription > subpass_descriptions {}; + std::vector< vk::SubpassDependency > dependencies {}; + + public: + + std::vector< vk::ClearValue > getClearValues() const { return m_clear_values; } + + template < typename SubpassT > + requires is_subpass< SubpassT > + void registerSubpass( SubpassT& subpass ) + { + subpass_descriptions.emplace_back( subpass.description() ); + + for ( auto& dependency : subpass.dependencies ) + { + dependencies.push_back( dependency ); + } + } + + template < is_attachment... Attachments > + void registerAttachments( Attachments&... attachments ) + { + attachment_descriptions.reserve( sizeof...( Attachments ) ); + m_clear_values.reserve( sizeof...( Attachments ) ); + + ( ( attachments.setIndex( static_cast< std::uint32_t >( attachment_descriptions.size() ) ), + attachment_descriptions.push_back( attachments.desc() ), + m_clear_values.push_back( attachments.m_clear_value ) ), + ... ); + } + + vk::raii::RenderPass create(); + }; + +} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/rendering/Subpass.hpp b/src/engine/rendering/Subpass.hpp index b0d6705..5b0218f 100644 --- a/src/engine/rendering/Subpass.hpp +++ b/src/engine/rendering/Subpass.hpp @@ -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, diff --git a/src/engine/rendering/SwapChain.cpp b/src/engine/rendering/SwapChain.cpp index fdb285f..54dd65c 100644 --- a/src/engine/rendering/SwapChain.cpp +++ b/src/engine/rendering/SwapChain.cpp @@ -8,7 +8,7 @@ #include #include "Attachment.hpp" -#include "RenderPass.hpp" +#include "RenderPassBuilder.hpp" #include "Subpass.hpp" #include "engine/assets/TransferManager.hpp" @@ -26,7 +26,18 @@ namespace fgl::engine old_swap_chain( nullptr ), m_swapchain( createSwapChain() ), m_swap_chain_images( createSwapchainImages() ), - render_attachments( getSwapChainImageFormat(), findDepthFormat() ) + render_attachments( getSwapChainImageFormat(), findDepthFormat() ), + m_render_pass( createRenderPass() ), + m_swap_chain_buffers( createFramebuffers() ), + m_clear_values( gatherClearValues( + render_attachments.color, + render_attachments.depth, + gbuffer.position, + gbuffer.normal, + gbuffer.albedo, + gbuffer.composite ) ), + m_gbuffer_descriptor_set( createGBufferDescriptors() ), + m_gbuffer_composite_descriptor_set( createCompositeDescriptors() ) { init(); } @@ -42,7 +53,18 @@ namespace fgl::engine old_swap_chain( previous ), m_swapchain( createSwapChain() ), m_swap_chain_images( createSwapchainImages() ), - render_attachments( getSwapChainImageFormat(), findDepthFormat() ) + render_attachments( getSwapChainImageFormat(), findDepthFormat() ), + m_render_pass( createRenderPass() ), + m_swap_chain_buffers( createFramebuffers() ), + m_clear_values( gatherClearValues( + render_attachments.color, + render_attachments.depth, + gbuffer.position, + gbuffer.normal, + gbuffer.albedo, + gbuffer.composite ) ), + m_gbuffer_descriptor_set( createGBufferDescriptors() ), + m_gbuffer_composite_descriptor_set( createCompositeDescriptors() ) { init(); old_swap_chain.reset(); @@ -50,8 +72,6 @@ namespace fgl::engine void SwapChain::init() { - createRenderPass(); - createFramebuffers(); createSyncObjects(); } @@ -67,7 +87,7 @@ namespace fgl::engine auto result { m_swapchain.acquireNextImage( std::numeric_limits< uint64_t >::max(), - imageAvailableSemaphores[ m_current_frame_index ] // must be a not signaled semaphore + image_available_sem[ m_current_frame_index ] // must be a not signaled semaphore ) }; return result; @@ -87,7 +107,7 @@ namespace fgl::engine vk::SubmitInfo m_submit_info {}; - std::vector< vk::Semaphore > wait_sems { imageAvailableSemaphores[ m_current_frame_index ], + std::vector< vk::Semaphore > wait_sems { image_available_sem[ m_current_frame_index ], memory::TransferManager::getInstance().getFinishedSem() }; std::vector< vk::PipelineStageFlags > wait_stages { vk::PipelineStageFlagBits::eColorAttachmentOutput, @@ -99,7 +119,7 @@ namespace fgl::engine m_submit_info.commandBufferCount = 1; m_submit_info.pCommandBuffers = &( *buffers ); - std::vector< vk::Semaphore > signaled_semaphores { renderFinishedSemaphores[ m_current_frame_index ] }; + std::vector< vk::Semaphore > signaled_semaphores { render_finished_sem[ m_current_frame_index ] }; m_submit_info.setSignalSemaphores( signaled_semaphores ); Device::getInstance().device().resetFences( fences ); @@ -201,45 +221,18 @@ namespace fgl::engine return images; } - void SwapChain::createRenderPass() + vk::raii::RenderPass SwapChain::createRenderPass() { ZoneScoped; //Present attachment - for ( int i = 0; i < imageCount(); ++i ) - { - auto& image { m_swap_chain_images[ i ] }; - - image.setName( "SwapChainImage: " + std::to_string( i ) ); - } - - render_attachments.color.linkImages( m_swap_chain_images ); - - gbuffer.position.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); - gbuffer.normal.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); - gbuffer.albedo.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); - gbuffer.composite.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); - + render_attachments.depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) ); gbuffer.position.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) ); gbuffer.normal.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) ); gbuffer.albedo.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) ); gbuffer.composite.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) ); - g_buffer_position_img = std::make_unique< Texture >( gbuffer.position.m_attachment_resources.m_images[ 0 ] - ->setName( "GBufferPosition" ) ); - g_buffer_normal_img = std::make_unique< Texture >( gbuffer.normal.m_attachment_resources.m_images[ 0 ] - ->setName( "GBufferNormal" ) ); - g_buffer_albedo_img = std::make_unique< Texture >( gbuffer.albedo.m_attachment_resources.m_images[ 0 ] - ->setName( "GBufferAlbedo" ) ); - g_buffer_composite_img = std::make_unique< Texture >( gbuffer.composite.m_attachment_resources.m_images[ 0 ] - ->setName( "GBufferComposite" ) ); - - RenderPass render_pass {}; - - render_attachments.depth.createResources( imageCount(), getSwapChainExtent() ); - render_attachments.depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) ); - - render_pass.registerAttachments( + render_pass_builder.registerAttachments( render_attachments.color, render_attachments.depth, gbuffer.position, @@ -247,50 +240,6 @@ namespace fgl::engine gbuffer.albedo, gbuffer.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, - *( gbuffer.position.resources().m_image_views[ i ].get() ), - vk::ImageLayout::eShaderReadOnlyOptimal ); - - set->bindAttachment( - 1, - *( gbuffer.normal.resources().m_image_views[ i ].get() ), - vk::ImageLayout::eShaderReadOnlyOptimal ); - - set->bindAttachment( - 2, - *( gbuffer.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( 1 ); - composite_set->bindAttachment( - 0, - *( gbuffer.composite.resources().m_image_views[ i ].get() ), - vk::ImageLayout::eShaderReadOnlyOptimal ); - - composite_set->update(); - - m_gbuffer_composite_descriptor_set[ i ] = std::move( composite_set ); - } - } - static_assert( is_attachment< ColoredPresentAttachment > ); static_assert( is_attachment< DepthAttachment > ); @@ -341,16 +290,6 @@ 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, @@ -362,10 +301,6 @@ namespace fgl::engine gui_subpass.registerDependencyFromExternal( vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput ); - /* - g_buffer_subpass -> composite_subpass -> gui_subpass - */ - gui_subpass.registerDependencyFrom( composite_subpass, vk::AccessFlagBits::eColorAttachmentWrite, @@ -374,9 +309,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, @@ -392,24 +324,51 @@ 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_clear_values = render_pass_builder.getClearValues(); - m_render_pass_resources = render_pass.resources( imageCount() ); - m_clear_values = render_pass.getClearValues(); + return render_pass_builder.create(); } - void SwapChain::createFramebuffers() + std::vector< vk::raii::Framebuffer > SwapChain::createFramebuffers() { ZoneScoped; - m_swap_chain_buffers.clear(); - m_swap_chain_buffers.reserve( imageCount() ); + + render_attachments.depth.createResources( imageCount(), getSwapChainExtent() ); + + render_attachments.color.linkImages( m_swap_chain_images ); + + gbuffer.position.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); + gbuffer.normal.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); + gbuffer.albedo.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); + gbuffer.composite.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); + + g_buffer_position_img = std::make_unique< Texture >( gbuffer.position.m_attachment_resources.m_images[ 0 ] + ->setName( "GBufferPosition" ) ); + g_buffer_normal_img = std::make_unique< Texture >( gbuffer.normal.m_attachment_resources.m_images[ 0 ] + ->setName( "GBufferNormal" ) ); + g_buffer_albedo_img = std::make_unique< Texture >( gbuffer.albedo.m_attachment_resources.m_images[ 0 ] + ->setName( "GBufferAlbedo" ) ); + g_buffer_composite_img = std::make_unique< Texture >( gbuffer.composite.m_attachment_resources.m_images[ 0 ] + ->setName( "GBufferComposite" ) ); + + std::vector< vk::raii::Framebuffer > framebuffers {}; + + framebuffers.reserve( imageCount() ); + for ( uint8_t i = 0; i < imageCount(); i++ ) { - std::vector< vk::ImageView > attachments { m_render_pass_resources->forFrame( i ) }; + std::vector< vk::ImageView > attachments { getViewsForFrame( + i, + render_attachments.color, + render_attachments.depth, + gbuffer.position, + gbuffer.normal, + gbuffer.albedo, + gbuffer.composite ) }; //Fill attachments for this frame const vk::Extent2D swapChainExtent { getSwapChainExtent() }; @@ -421,15 +380,17 @@ namespace fgl::engine framebufferInfo.height = swapChainExtent.height; framebufferInfo.layers = 1; - m_swap_chain_buffers.push_back( Device::getInstance()->createFramebuffer( framebufferInfo ) ); + framebuffers.push_back( Device::getInstance()->createFramebuffer( framebufferInfo ) ); } + + return framebuffers; } void SwapChain::createSyncObjects() { ZoneScoped; - imageAvailableSemaphores.reserve( MAX_FRAMES_IN_FLIGHT ); - renderFinishedSemaphores.reserve( MAX_FRAMES_IN_FLIGHT ); + image_available_sem.reserve( MAX_FRAMES_IN_FLIGHT ); + render_finished_sem.reserve( MAX_FRAMES_IN_FLIGHT ); in_flight_fence.reserve( MAX_FRAMES_IN_FLIGHT ); images_in_flight.resize( imageCount(), VK_NULL_HANDLE ); @@ -442,8 +403,8 @@ namespace fgl::engine { auto& device { Device::getInstance() }; - imageAvailableSemaphores.push_back( device->createSemaphore( semaphoreInfo ) ); - renderFinishedSemaphores.push_back( device->createSemaphore( semaphoreInfo ) ); + image_available_sem.push_back( device->createSemaphore( semaphoreInfo ) ); + render_finished_sem.push_back( device->createSemaphore( semaphoreInfo ) ); in_flight_fence.push_back( device->createFence( fenceInfo ) ); } } @@ -534,6 +495,53 @@ namespace fgl::engine } } + std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > SwapChain:: + createGBufferDescriptors() + { + std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > data; + + 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, gbuffer.position.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); + + set->bindAttachment( 1, gbuffer.normal.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); + + set->bindAttachment( 2, gbuffer.albedo.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); + + set->update(); + + data[ i ] = std::move( set ); + } + + return data; + } + + std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > SwapChain:: + createCompositeDescriptors() + { + std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > data; + + for ( int i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i ) + { + auto composite_set { + std::make_unique< descriptors::DescriptorSet >( GBufferCompositeDescriptorSet::createLayout() ) + }; + + composite_set->setMaxIDX( 1 ); + composite_set->bindAttachment( 0, gbuffer.composite.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); + + composite_set->update(); + + data[ i ] = std::move( composite_set ); + } + + return data; + } + vk::Format SwapChain::findDepthFormat() { ZoneScoped; diff --git a/src/engine/rendering/SwapChain.hpp b/src/engine/rendering/SwapChain.hpp index 002d7c1..11d3653 100644 --- a/src/engine/rendering/SwapChain.hpp +++ b/src/engine/rendering/SwapChain.hpp @@ -6,7 +6,7 @@ #include #include "Device.hpp" -#include "RenderPass.hpp" +#include "RenderPassBuilder.hpp" #include "engine/FrameInfo.hpp" #include "engine/texture/Texture.hpp" @@ -49,18 +49,6 @@ namespace fgl::engine ColorAttachment composite { vk::Format::eR8G8B8A8Unorm }; } gbuffer {}; - 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< vk::raii::Semaphore > imageAvailableSemaphores {}; - std::vector< vk::raii::Semaphore > renderFinishedSemaphores {}; - std::vector< vk::raii::Fence > in_flight_fence {}; - std::vector< vk::Fence > images_in_flight {}; - size_t m_current_frame_index { 0 }; - - std::vector< vk::ClearValue > m_clear_values {}; - public: std::unique_ptr< Texture > g_buffer_position_img { nullptr }; @@ -70,11 +58,31 @@ namespace fgl::engine private: + RenderPassBuilder render_pass_builder {}; + + vk::raii::RenderPass m_render_pass; + + std::vector< vk::raii::Framebuffer > m_swap_chain_buffers; + + std::vector< vk::ClearValue > m_clear_values; + + std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > + m_gbuffer_descriptor_set; + + std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > + m_gbuffer_composite_descriptor_set; + + std::vector< vk::raii::Semaphore > image_available_sem {}; + std::vector< vk::raii::Semaphore > render_finished_sem {}; + std::vector< vk::raii::Fence > in_flight_fence {}; + std::vector< vk::Fence > images_in_flight {}; + size_t m_current_frame_index { 0 }; + void init(); [[nodiscard]] vk::raii::SwapchainKHR createSwapChain(); [[nodiscard]] std::vector< Image > createSwapchainImages(); - void createRenderPass(); - void createFramebuffers(); + [[nodiscard]] vk::raii::RenderPass createRenderPass(); + [[nodiscard]] std::vector< vk::raii::Framebuffer > createFramebuffers(); void createSyncObjects(); // Helper functions @@ -82,11 +90,32 @@ namespace fgl::engine vk::PresentModeKHR chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >& availablePresentModes ); vk::Extent2D chooseSwapExtent( const vk::SurfaceCapabilitiesKHR& capabilities ); - std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > - m_gbuffer_descriptor_set {}; + template < is_attachment... Attachments > + static std::vector< vk::ImageView > getViewsForFrame( const std::uint8_t frame_idx, Attachments... attachments ) + { + std::vector< vk::ImageView > view {}; + view.resize( sizeof...( Attachments ) ); + + ( ( view[ attachments.getIndex() ] = *attachments.getView( frame_idx ) ), ... ); + + return view; + } + + template < is_attachment... Attachments > + static std::vector< vk::ClearValue > gatherClearValues( Attachments... attachments ) + { + std::vector< vk::ClearValue > clear_values {}; + clear_values.resize( sizeof...( Attachments ) ); + + ( ( clear_values[ attachments.getIndex() ] = attachments.m_clear_value ), ... ); + + return clear_values; + } std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > - m_gbuffer_composite_descriptor_set {}; + createGBufferDescriptors(); + std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > + createCompositeDescriptors(); public: