diff --git a/shaders/gui-compose.frag b/shaders/gui-compose.frag index 7eae4dc..d1ba96c 100644 --- a/shaders/gui-compose.frag +++ b/shaders/gui-compose.frag @@ -10,6 +10,4 @@ void main() { vec4 composite = subpassLoad(i_composite).xyzw; out_color = composite; -} - - +} \ No newline at end of file diff --git a/src/engine/EngineContext.cpp b/src/engine/EngineContext.cpp index bf29652..85c03a3 100644 --- a/src/engine/EngineContext.cpp +++ b/src/engine/EngineContext.cpp @@ -151,12 +151,13 @@ namespace fgl::engine if ( auto& command_buffer = m_renderer.beginFrame(); *command_buffer ) { ZoneScopedN( "Render" ); - //Update - const std::uint16_t frame_index { m_renderer.getFrameIndex() }; + const FrameIndex frame_index { m_renderer.getFrameIndex() }; + const PresentIndex present_idx { m_renderer.getPresentIndex() }; const auto view_frustum { camera.getFrustumBounds() }; FrameInfo frame_info { frame_index, + present_idx, delta_time, command_buffer, { camera, viewer.getTransform() }, @@ -167,8 +168,8 @@ namespace fgl::engine draw_parameter_buffers[ frame_index ], *this->m_vertex_buffer, *this->m_index_buffer, - m_renderer.getGBufferDescriptor( frame_index ), - m_renderer.getGBufferCompositeDescriptor( frame_index ), + m_renderer.getGBufferDescriptor( present_idx ), + m_renderer.getGBufferCompositeDescriptor( present_idx ), view_frustum, this->m_renderer.getSwapChain() }; diff --git a/src/engine/FrameInfo.hpp b/src/engine/FrameInfo.hpp index ee423e5..214504c 100644 --- a/src/engine/FrameInfo.hpp +++ b/src/engine/FrameInfo.hpp @@ -15,6 +15,7 @@ #include "engine/descriptors/DescriptorSet.hpp" #include "engine/descriptors/DescriptorSetLayout.hpp" #include "engine/tree/octtree/OctTreeNode.hpp" +#include "rendering/types.hpp" #define MAX_LIGHTS 10 @@ -75,7 +76,8 @@ namespace fgl::engine struct FrameInfo { - std::uint16_t frame_idx; + FrameIndex frame_idx; + PresentIndex present_idx; float frame_time; vk::raii::CommandBuffer& command_buffer; diff --git a/src/engine/concepts/is_attachment.hpp b/src/engine/concepts/is_attachment.hpp index b0f6511..a8edbe6 100644 --- a/src/engine/concepts/is_attachment.hpp +++ b/src/engine/concepts/is_attachment.hpp @@ -4,6 +4,8 @@ #pragma once +#include + namespace fgl::engine { class ImageView; @@ -22,10 +24,13 @@ namespace fgl::engine a.setIndex( std::declval< std::uint32_t >() ) }; { - a.linkImages( std::declval< std::vector< std::shared_ptr< Image > >& >() ) + a.attachImageView( std::declval< std::uint16_t >(), std::declval< std::shared_ptr< ImageView > >() ) }; { - a.view( std::declval< std::uint32_t >() ) + a.linkImage( std::declval< std::uint16_t >(), std::declval< Image& >() ) + }; + { + a.getView( std::declval< std::uint8_t >() ) } -> std::same_as< ImageView& >; { a.m_clear_value diff --git a/src/engine/gui/preview.cpp b/src/engine/gui/preview.cpp index 4d3d60a..df06c90 100644 --- a/src/engine/gui/preview.cpp +++ b/src/engine/gui/preview.cpp @@ -98,6 +98,8 @@ namespace fgl::engine::gui void drawRenderingOutputs( FrameInfo& info ) { ZoneScoped; + const auto present_idx { info.present_idx }; + ImGui::Begin( "RenderOutputs" ); enum RenderingOutputSelection : std::uint_fast8_t @@ -139,8 +141,7 @@ namespace fgl::engine::gui current = Composite; } - /* - info.swap_chain.g_buffer_albedo_img->drawImGui( { v_size, h_size } ); + info.swap_chain.g_buffer_albedo_img[ present_idx ]->drawImGui( { v_size, h_size } ); ImGui::SameLine(); if ( ImGui::Selectable( options[ Albedo ], current == Albedo ) ) { @@ -148,7 +149,7 @@ namespace fgl::engine::gui current = Albedo; } - info.swap_chain.g_buffer_normal_img->drawImGui( { v_size, h_size } ); + info.swap_chain.g_buffer_normal_img[ present_idx ]->drawImGui( { v_size, h_size } ); ImGui::SameLine(); if ( ImGui::Selectable( options[ Normal ], current == Normal ) ) { @@ -156,37 +157,34 @@ namespace fgl::engine::gui current = Normal; } - info.swap_chain.g_buffer_position_img->drawImGui( { v_size, h_size } ); + info.swap_chain.g_buffer_position_img[ present_idx ]->drawImGui( { v_size, h_size } ); ImGui::SameLine(); if ( ImGui::Selectable( options[ Position ], current == Position ) ) { log::debug( "Changing output to Position" ); current = Position; } - */ ImGui::EndCombo(); } - /* switch ( current ) { default: [[fallthrough]]; - case Composite: - info.swap_chain.g_buffer_composite_img->drawImGui(); + info.swap_chain.g_buffer_composite_img[ present_idx ]->drawImGui(); break; case Albedo: - info.swap_chain.g_buffer_albedo_img->drawImGui(); + info.swap_chain.g_buffer_albedo_img[ present_idx ]->drawImGui(); break; case Normal: - info.swap_chain.g_buffer_normal_img->drawImGui(); + info.swap_chain.g_buffer_normal_img[ present_idx ]->drawImGui(); break; case Position: - info.swap_chain.g_buffer_position_img->drawImGui(); + info.swap_chain.g_buffer_position_img[ present_idx ]->drawImGui(); break; - }*/ + } handleDragDrop( info ); diff --git a/src/engine/rendering/Attachment.hpp b/src/engine/rendering/Attachment.hpp index 9221113..b145c31 100644 --- a/src/engine/rendering/Attachment.hpp +++ b/src/engine/rendering/Attachment.hpp @@ -13,8 +13,7 @@ #include "engine/concepts/is_attachment.hpp" #include "engine/image/Image.hpp" -#include "engine/image/ImageView.hpp" -#include "types.hpp" +#include "engine/rendering/Device.hpp" namespace fgl::engine { @@ -34,7 +33,7 @@ namespace fgl::engine class Attachment { vk::AttachmentDescription description {}; - std::uint32_t m_index { std::numeric_limits< std::uint32_t >::max() }; + std::uint32_t index { std::numeric_limits< std::uint32_t >::max() }; public: @@ -44,22 +43,9 @@ 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 ) { m_index = idx; } + void setIndex( const std::uint32_t idx ) { index = idx; } constexpr static vk::AttachmentLoadOp loadOp = load_op; constexpr static vk::AttachmentStoreOp storeOp = store_op; @@ -79,18 +65,21 @@ namespace fgl::engine description.finalLayout = final_layout; } - void linkImage( std::shared_ptr< Image > image ) + void attachImageView( std::uint16_t frame_idx, std::shared_ptr< ImageView > image_view ) { - auto& itter { m_attachment_resources.m_images.emplace_back( std::move( image ) ) }; - m_attachment_resources.m_image_views.emplace_back( itter->getView() ); + auto& image_views = m_attachment_resources.m_image_views; + if ( image_views.size() <= frame_idx ) image_views.resize( frame_idx + 1 ); + image_views[ frame_idx ] = std::move( image_view ); } - void linkImages( std::vector< std::shared_ptr< Image > >& images ) + void linkImage( std::uint16_t frame_idx, Image& image ) { attachImageView( frame_idx, image.getView() ); } + + void linkImages( std::vector< Image >& images ) { - for ( auto image : images ) + assert( images.size() > 0 ); + for ( std::uint16_t i = 0; i < images.size(); ++i ) { - auto& itter { m_attachment_resources.m_images.emplace_back( std::move( image ) ) }; - m_attachment_resources.m_image_views.emplace_back( itter->getView() ); + linkImage( i, images[ i ] ); } } @@ -110,59 +99,37 @@ namespace fgl::engine } } - //! Creates resources required for this attachment + //! Creates a resource that is used across all frames 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() ); } } + 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; } std::uint32_t getIndex() const { assert( - m_index != std::numeric_limits< std::uint32_t >::max() + index != std::numeric_limits< std::uint32_t >::max() && "Attachment must be registered in RenderPass before use" ); - return m_index; - } - - ImageView& view( const FrameIndex index ) - { - assert( index < m_attachment_resources.m_image_views.size() ); - return *m_attachment_resources.m_image_views[ index ]; - } - - Image& image( const FrameIndex index ) - { - assert( index < m_attachment_resources.m_images.size() ); - 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() ); - assert( images.size() > 0 ); - - for ( std::size_t i = 0; i < images.size(); ++i ) - { - images[ i ]->setName( str ); - image_views[ i ]->setName( str ); - } + return index; } friend class RenderPassBuilder; diff --git a/src/engine/rendering/RenderPassBuilder.hpp b/src/engine/rendering/RenderPassBuilder.hpp index 4999dfd..a8aa15b 100644 --- a/src/engine/rendering/RenderPassBuilder.hpp +++ b/src/engine/rendering/RenderPassBuilder.hpp @@ -10,27 +10,6 @@ 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 RenderPassBuilder { std::vector< vk::AttachmentDescription > attachment_descriptions {}; @@ -39,8 +18,6 @@ namespace fgl::engine 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; } @@ -69,30 +46,6 @@ namespace fgl::engine ... ); } - 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(); }; diff --git a/src/engine/rendering/Renderer.cpp b/src/engine/rendering/Renderer.cpp index 17c00e9..f0ae9d2 100644 --- a/src/engine/rendering/Renderer.cpp +++ b/src/engine/rendering/Renderer.cpp @@ -74,7 +74,7 @@ namespace fgl::engine void Renderer::recreateSwapchain() { ZoneScoped; - log::info( "Rebuilding swapchain" ); + std::cout << "Rebuilding swap chain" << std::endl; auto extent { m_window.getExtent() }; while ( extent.width == 0 || extent.height == 0 ) @@ -145,8 +145,7 @@ namespace fgl::engine throw std::runtime_error( "Failed to submit commmand buffer" ); is_frame_started = false; - current_frame_index = - static_cast< std::uint16_t >( ( current_frame_index + 1 ) % SwapChain::MAX_FRAMES_IN_FLIGHT ); + current_frame_idx = static_cast< std::uint16_t >( ( current_frame_idx + 1 ) % SwapChain::MAX_FRAMES_IN_FLIGHT ); } void Renderer::setViewport( const vk::raii::CommandBuffer& buffer ) @@ -182,7 +181,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( current_frame_index, current_present_index ); + render_pass_info.framebuffer = m_swapchain->getFrameBuffer( 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(); diff --git a/src/engine/rendering/Renderer.hpp b/src/engine/rendering/Renderer.hpp index 2589e06..17c7217 100644 --- a/src/engine/rendering/Renderer.hpp +++ b/src/engine/rendering/Renderer.hpp @@ -11,6 +11,7 @@ #include "Device.hpp" #include "SwapChain.hpp" +#include "engine/Window.hpp" //clang-format: off #include @@ -32,7 +33,7 @@ namespace fgl::engine std::optional< TracyVkCtx > m_tracy_ctx { std::nullopt }; PresentIndex current_present_index { std::numeric_limits< PresentIndex >::max() }; - FrameIndex current_frame_index { 0 }; + FrameIndex current_frame_idx { 0 }; bool is_frame_started { false }; void createCommandBuffers(); @@ -50,10 +51,16 @@ namespace fgl::engine return m_swapchain->getGBufferCompositeDescriptor( frame_idx ); } - std::uint16_t getFrameIndex() const + FrameIndex getFrameIndex() const { assert( is_frame_started && "Cannot get frame index while frame not in progress" ); - return current_frame_index; + return current_frame_idx; + } + + PresentIndex getPresentIndex() const + { + assert( current_present_index != std::numeric_limits< PresentIndex >::max() ); + return current_present_index; } bool isFrameInProgress() const { return is_frame_started; } @@ -61,10 +68,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_index ]; + return m_command_buffer[ current_frame_idx ]; } - vk::raii::CommandBuffer& getCurrentGuiCommandBuffer() { return m_gui_command_buffer[ current_frame_index ]; } + vk::raii::CommandBuffer& getCurrentGuiCommandBuffer() { return m_gui_command_buffer[ current_frame_idx ]; } TracyVkCtx getCurrentTracyCTX() const { diff --git a/src/engine/rendering/Subpass.hpp b/src/engine/rendering/Subpass.hpp index 35c652e..8a3e8f6 100644 --- a/src/engine/rendering/Subpass.hpp +++ b/src/engine/rendering/Subpass.hpp @@ -198,17 +198,17 @@ namespace fgl::engine void registerDependencyToExternal( const vk::AccessFlags src_access_flags, const vk::PipelineStageFlags src_stage_flags, - const vk::AccessFlags dst_access_flags, - const vk::PipelineStageFlags dst_stage_flags, - const vk::DependencyFlags dependency_flags ) + const vk::AccessFlags dst_access_flags = vk::AccessFlagBits::eNone, + const vk::PipelineStageFlags dst_stage_flags = vk::PipelineStageFlagBits::eNone, + const vk::DependencyFlags dependency_flags = {} ) { registerDependency( this->getIndex(), VK_SUBPASS_EXTERNAL, src_access_flags, src_stage_flags, - dst_access_flags, - dst_stage_flags, + dst_access_flags == vk::AccessFlagBits::eNone ? src_access_flags : dst_access_flags, + dst_stage_flags == vk::PipelineStageFlagBits::eNone ? src_stage_flags : dst_stage_flags, dependency_flags ); } }; diff --git a/src/engine/rendering/SwapChain.cpp b/src/engine/rendering/SwapChain.cpp index 7ef397e..8fb5411 100644 --- a/src/engine/rendering/SwapChain.cpp +++ b/src/engine/rendering/SwapChain.cpp @@ -17,63 +17,69 @@ namespace fgl::engine SwapChain::SwapChain( const vk::Extent2D extent, PhysicalDevice& phy_device ) : m_phy_device( phy_device ), - m_swapchain_support( Device::getInstance().getSwapChainSupport() ), - m_surface_format( chooseSwapSurfaceFormat( m_swapchain_support.formats ) ), + m_swapchain_details( Device::getInstance().getSwapChainSupport() ), + m_surface_format( chooseSwapSurfaceFormat( m_swapchain_details.formats ) ), + m_present_mode( chooseSwapPresentMode( m_swapchain_details.presentModes ) ), + m_swapchain_extent( extent ), m_swap_chain_format( m_surface_format.format ), m_swap_chain_depth_format( findDepthFormat() ), - m_swap_chain_extent( chooseSwapExtent( m_swapchain_support.capabilities ) ), - m_swapchain_extent( extent ), + old_swap_chain( nullptr ), m_swapchain( createSwapChain() ), m_swap_chain_images( createSwapchainImages() ), - m_render_attachments( getSwapChainImageFormat(), findDepthFormat() ), + render_attachments( getSwapChainImageFormat(), findDepthFormat() ), m_render_pass( createRenderPass() ), m_swap_chain_buffers( createFramebuffers() ), - m_clear_values( populateAttachmentClearValues() ), + 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( createGBufferCompositeDescriptors() ) + m_composite_descriptor_set( createCompositeDescriptors() ) { init(); } 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_swapchain_details( Device::getInstance().getSwapChainSupport() ), + m_surface_format( chooseSwapSurfaceFormat( m_swapchain_details.formats ) ), + m_present_mode( chooseSwapPresentMode( m_swapchain_details.presentModes ) ), + m_swapchain_extent( extent ), m_swap_chain_format( m_surface_format.format ), m_swap_chain_depth_format( findDepthFormat() ), - m_swap_chain_extent( chooseSwapExtent( m_swapchain_support.capabilities ) ), - m_swapchain_extent( extent ), + old_swap_chain( previous ), m_swapchain( createSwapChain() ), m_swap_chain_images( createSwapchainImages() ), - m_render_attachments( getSwapChainImageFormat(), findDepthFormat() ), + render_attachments( getSwapChainImageFormat(), findDepthFormat() ), m_render_pass( createRenderPass() ), m_swap_chain_buffers( createFramebuffers() ), - m_clear_values( populateAttachmentClearValues() ), + 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( createGBufferCompositeDescriptors() ) + m_composite_descriptor_set( createCompositeDescriptors() ) { 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() { createSyncObjects(); } - std::pair< vk::Result, std::uint32_t > SwapChain::acquireNextImage() + std::pair< vk::Result, PresentIndex > SwapChain::acquireNextImage() { ZoneScoped; - std::vector< vk::Fence > fences { in_flight_fences[ current_frame_index ] }; + std::vector< vk::Fence > fences { in_flight_fence[ m_current_frame_index ] }; if ( Device::getInstance().device().waitForFences( fences, VK_TRUE, std::numeric_limits< uint64_t >::max() ) != vk::Result::eSuccess ) @@ -81,47 +87,47 @@ namespace fgl::engine auto result { m_swapchain.acquireNextImage( std::numeric_limits< uint64_t >::max(), - imageAvailableSemaphores[ current_frame_index ] // must be a not signaled semaphore + image_available_sem[ m_current_frame_index ] // must be a not signaled semaphore ) }; return result; } vk::Result SwapChain:: - submitCommandBuffers( const vk::raii::CommandBuffer& buffers, const PresentIndex current_present_index ) + submitCommandBuffers( const vk::raii::CommandBuffer& buffers, const PresentIndex present_index ) { ZoneScoped; - images_in_flight[ current_present_index ] = in_flight_fences[ current_frame_index ]; + images_in_flight[ present_index ] = in_flight_fence[ m_current_frame_index ]; - std::vector< vk::Fence > fences { images_in_flight[ current_present_index ] }; + std::vector< vk::Fence > fences { images_in_flight[ present_index ] }; if ( Device::getInstance().device().waitForFences( fences, VK_TRUE, std::numeric_limits< uint64_t >::max() ) != vk::Result::eSuccess ) throw std::runtime_error( "failed to wait for fences!" ); - vk::SubmitInfo submitInfo {}; + vk::SubmitInfo m_submit_info {}; - std::vector< vk::Semaphore > wait_sems { imageAvailableSemaphores[ 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, vk::PipelineStageFlagBits::eTopOfPipe }; - submitInfo.setWaitSemaphores( wait_sems ); - submitInfo.setWaitDstStageMask( wait_stages ); + m_submit_info.setWaitSemaphores( wait_sems ); + m_submit_info.setWaitDstStageMask( wait_stages ); - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &( *buffers ); + m_submit_info.commandBufferCount = 1; + m_submit_info.pCommandBuffers = &( *buffers ); - std::vector< vk::Semaphore > signaled_semaphores { renderFinishedSemaphores[ current_frame_index ] }; - submitInfo.setSignalSemaphores( signaled_semaphores ); + std::vector< vk::Semaphore > signaled_semaphores { render_finished_sem[ m_current_frame_index ] }; + m_submit_info.setSignalSemaphores( signaled_semaphores ); Device::getInstance().device().resetFences( fences ); - std::vector< vk::SubmitInfo > submit_infos { submitInfo }; + std::vector< vk::SubmitInfo > submit_infos { m_submit_info }; - Device::getInstance().graphicsQueue().submit( submitInfo, in_flight_fences[ current_frame_index ] ); + Device::getInstance().graphicsQueue().submit( m_submit_info, in_flight_fence[ m_current_frame_index ] ); vk::PresentInfoKHR presentInfo = {}; @@ -130,7 +136,7 @@ namespace fgl::engine std::vector< vk::SwapchainKHR > swapchains { m_swapchain }; presentInfo.setSwapchains( swapchains ); - std::array< std::uint32_t, 1 > indicies { { current_present_index } }; + std::array< std::uint32_t, 1 > indicies { { present_index } }; presentInfo.setImageIndices( indicies ); if ( auto present_result = Device::getInstance().presentQueue().presentKHR( presentInfo ); @@ -141,7 +147,7 @@ namespace fgl::engine throw std::runtime_error( "failed to present swap chain image!" ); } - current_frame_index = ( current_frame_index + 1 ) % MAX_FRAMES_IN_FLIGHT; + m_current_frame_index = ( m_current_frame_index + 1 ) % MAX_FRAMES_IN_FLIGHT; return vk::Result::eSuccess; } @@ -150,24 +156,22 @@ namespace fgl::engine { ZoneScoped; - const vk::PresentModeKHR present_mode { chooseSwapPresentMode( m_swapchain_support.presentModes ) }; - - uint32_t image_count = m_swapchain_support.capabilities.minImageCount + 1; - if ( m_swapchain_support.capabilities.maxImageCount > 0 - && image_count > m_swapchain_support.capabilities.maxImageCount ) + std::uint32_t image_count { m_swapchain_details.capabilities.minImageCount + 1 }; + if ( m_swapchain_details.capabilities.maxImageCount > 0 + && image_count > m_swapchain_details.capabilities.maxImageCount ) { - image_count = m_swapchain_support.capabilities.maxImageCount; + image_count = m_swapchain_details.capabilities.maxImageCount; } - vk::SwapchainCreateInfoKHR create_info = {}; - create_info.surface = Device::getInstance().surface(); + vk::SwapchainCreateInfoKHR createInfo = {}; + createInfo.surface = Device::getInstance().surface(); - create_info.minImageCount = image_count; - create_info.imageFormat = m_surface_format.format; - create_info.imageColorSpace = m_surface_format.colorSpace; - create_info.imageExtent = m_swap_chain_extent; - create_info.imageArrayLayers = 1; - create_info.imageUsage = vk::ImageUsageFlagBits::eColorAttachment; + createInfo.minImageCount = image_count; + createInfo.imageFormat = m_surface_format.format; + createInfo.imageColorSpace = m_surface_format.colorSpace; + createInfo.imageExtent = m_swapchain_extent; + createInfo.imageArrayLayers = 1; + createInfo.imageUsage = vk::ImageUsageFlagBits::eColorAttachment; const std::uint32_t graphics_family { m_phy_device.queueInfo().getIndex( vk::QueueFlagBits::eGraphics ) }; const std::uint32_t present_family { m_phy_device.queueInfo().getPresentIndex() }; @@ -178,61 +182,58 @@ namespace fgl::engine { // If the familys are not the same then the swapchain must be shared between // both queues. - create_info.imageSharingMode = vk::SharingMode::eConcurrent; - create_info.queueFamilyIndexCount = 2; - create_info.pQueueFamilyIndices = queueFamilyIndices; + createInfo.imageSharingMode = vk::SharingMode::eConcurrent; + createInfo.queueFamilyIndexCount = 2; + createInfo.pQueueFamilyIndices = queueFamilyIndices; } else { - create_info.imageSharingMode = vk::SharingMode::eExclusive; - create_info.queueFamilyIndexCount = 0; // Optional - create_info.pQueueFamilyIndices = nullptr; // Optional + createInfo.imageSharingMode = vk::SharingMode::eExclusive; + createInfo.queueFamilyIndexCount = 0; // Optional + createInfo.pQueueFamilyIndices = nullptr; // Optional } - create_info.preTransform = m_swapchain_support.capabilities.currentTransform; - create_info.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque; + createInfo.preTransform = m_swapchain_details.capabilities.currentTransform; + createInfo.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque; - create_info.presentMode = present_mode; - create_info.clipped = VK_TRUE; + createInfo.presentMode = m_present_mode; + createInfo.clipped = VK_TRUE; - create_info.oldSwapchain = ( old_swap_chain == nullptr ? VK_NULL_HANDLE : *old_swap_chain->m_swapchain ); + createInfo.oldSwapchain = old_swap_chain == nullptr ? VK_NULL_HANDLE : *old_swap_chain->m_swapchain; - return Device::getInstance()->createSwapchainKHR( create_info ); + return Device::getInstance()->createSwapchainKHR( createInfo ); } - std::vector< std::shared_ptr< Image > > SwapChain::createSwapchainImages() + std::vector< Image > SwapChain::createSwapchainImages() { std::vector< vk::Image > swap_chain_images { m_swapchain.getImages() }; - std::vector< std::shared_ptr< Image > > images {}; - images.reserve( swap_chain_images.size() ); + std::vector< Image > images {}; - for ( std::uint64_t i = 0; i < swap_chain_images.size(); ++i ) + for ( std::uint64_t i = 0; i < swap_chain_images.size(); i++ ) { - images.emplace_back( std::make_shared< Image >( - m_swap_chain_extent, + auto& itter = images.emplace_back( + m_swapchain_extent, m_surface_format.format, swap_chain_images[ i ], - vk::ImageUsageFlagBits::eColorAttachment ) ); + vk::ImageUsageFlagBits::eColorAttachment ); + itter.setName( "Swapchain image: " + std::to_string( i ) ); } - assert( swap_chain_images.size() == images.size() ); - return images; } vk::raii::RenderPass SwapChain::createRenderPass() { ZoneScoped; - - RenderPassBuilder render_pass_builder {}; + //Present attachment 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 ); + render_attachments.color, + render_attachments.depth, + gbuffer.position, + gbuffer.normal, + gbuffer.albedo, + gbuffer.composite ); static_assert( is_attachment< ColoredPresentAttachment > ); static_assert( is_attachment< DepthAttachment > ); @@ -243,11 +244,7 @@ namespace fgl::engine UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal >, UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal >, UsedAttachment< ColorAttachment, vk::ImageLayout::eColorAttachmentOptimal > > - g_buffer_subpass { 0, - m_render_attachments.depth, - m_gbuffer_attachments.position, - m_gbuffer_attachments.normal, - m_gbuffer_attachments.albedo }; + g_buffer_subpass { 0, render_attachments.depth, gbuffer.position, gbuffer.normal, gbuffer.albedo }; g_buffer_subpass.registerDependencyFromExternal( vk::AccessFlagBits::eDepthStencilAttachmentWrite, @@ -258,17 +255,11 @@ namespace fgl::engine 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, - m_render_attachments.depth, - m_gbuffer_attachments.composite, - m_gbuffer_attachments.position, - m_gbuffer_attachments.normal, - m_gbuffer_attachments.albedo }; + composite_subpass { 1, gbuffer.composite, gbuffer.position, gbuffer.normal, gbuffer.albedo }; composite_subpass.registerDependencyFromExternal( vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput ); @@ -282,14 +273,11 @@ namespace fgl::engine 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::eShaderRead | vk::AccessFlagBits::eInputAttachmentRead, + vk::PipelineStageFlagBits::eFragmentShader ); // 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< @@ -297,15 +285,22 @@ namespace fgl::engine UsedAttachment< DepthAttachment, vk::ImageLayout::eDepthStencilAttachmentOptimal >, UsedAttachment< ColoredPresentAttachment, vk::ImageLayout::eColorAttachmentOptimal >, InputAttachment< ColorAttachment, vk::ImageLayout::eShaderReadOnlyOptimal > > - gui_subpass { 2, m_render_attachments.depth, m_render_attachments.color, m_gbuffer_attachments.composite }; + gui_subpass { 2, render_attachments.depth, render_attachments.color, gbuffer.composite }; + + gui_subpass.registerFullDependency( composite_subpass ); + + // For depth attachment + gui_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 ); gui_subpass.registerDependencyFromExternal( vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput ); - /* - g_buffer_subpass -> composite_subpass -> gui_subpass - */ - gui_subpass.registerDependencyFrom( composite_subpass, vk::AccessFlagBits::eColorAttachmentWrite, @@ -323,11 +318,7 @@ namespace fgl::engine vk::DependencyFlagBits::eByRegion ); gui_subpass.registerDependencyToExternal( - vk::AccessFlagBits::eColorAttachmentWrite, - vk::PipelineStageFlagBits::eColorAttachmentOutput, - vk::AccessFlagBits::eMemoryRead, - vk::PipelineStageFlagBits::eBottomOfPipe, - vk::DependencyFlagBits::eByRegion ); + vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput ); render_pass_builder.registerSubpass( g_buffer_subpass ); render_pass_builder.registerSubpass( composite_subpass ); @@ -336,81 +327,69 @@ namespace fgl::engine return render_pass_builder.create(); } - template < is_attachment... Attachments > - std::vector< std::shared_ptr< ImageView > > - fillViewsFromAttachments( uint8_t frame_idx, Attachments&&... attachments ) - { - std::vector< std::shared_ptr< ImageView > > views {}; - - views.resize( sizeof...( Attachments ) ); - - ( ( attachments.fillVec( frame_idx, views ) ), ... ); - - return views; - } - - std::vector< std::vector< vk::raii::Framebuffer > > SwapChain::createFramebuffers() + std::vector< vk::raii::Framebuffer > SwapChain::createFramebuffers() { ZoneScoped; - assert( imageCount() > 0 ); + render_attachments.color.linkImages( m_swap_chain_images ); - m_render_attachments.color.linkImages( m_swap_chain_images ); + render_attachments.depth.createResources( imageCount(), getSwapChainExtent() ); + render_attachments.depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) ); - m_render_attachments.depth.createResources( imageCount(), getSwapChainExtent() ); - m_render_attachments.depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) ); + gbuffer.position.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); + gbuffer.position.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) ); - // 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 ); + gbuffer.normal.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); + gbuffer.normal.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) ); - 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 } } ) ); - ; + gbuffer.albedo.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); + gbuffer.albedo.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) ); - std::vector< std::vector< vk::raii::Framebuffer > > framebuffers {}; + gbuffer.composite.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled ); + gbuffer.composite.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) ); - for ( std::uint16_t present_idx = 0; present_idx < imageCount(); ++present_idx ) + for ( PresentIndex i = 0; i < imageCount(); ++i ) { - std::vector< vk::raii::Framebuffer > temp {}; + g_buffer_position_img.emplace_back( std::make_unique< Texture >( gbuffer.position.m_attachment_resources + .m_images[ i ] + ->setName( "GBufferPosition" ) ) ); + g_buffer_normal_img.emplace_back( std::make_unique< Texture >( gbuffer.normal.m_attachment_resources + .m_images[ i ] + ->setName( "GBufferNormal" ) ) ); + g_buffer_albedo_img.emplace_back( std::make_unique< Texture >( gbuffer.albedo.m_attachment_resources + .m_images[ i ] + ->setName( "GBufferAlbedo" ) ) ); + g_buffer_composite_img.emplace_back( std::make_unique< Texture >( gbuffer.composite.m_attachment_resources + .m_images[ i ] + ->setName( "GBufferComposite" ) ) ); + } - for ( FrameIndex frame_idx = 0; frame_idx < SwapChain::MAX_FRAMES_IN_FLIGHT; frame_idx++ ) - { - std::vector< vk::ImageView > attachments {}; + std::vector< vk::raii::Framebuffer > framebuffers {}; - 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 ) ); + framebuffers.reserve( imageCount() ); - //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; + for ( uint8_t i = 0; i < imageCount(); i++ ) + { + std::vector< vk::ImageView > attachments { getViewsForFrame( + i, + render_attachments.color, + render_attachments.depth, + gbuffer.position, + gbuffer.normal, + gbuffer.albedo, + gbuffer.composite ) }; - temp.emplace_back( Device::getInstance()->createFramebuffer( framebufferInfo ) ); - } + //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; - framebuffers.emplace_back( std::move( temp ) ); + framebuffers.push_back( Device::getInstance()->createFramebuffer( framebufferInfo ) ); } return framebuffers; @@ -419,9 +398,9 @@ namespace fgl::engine void SwapChain::createSyncObjects() { ZoneScoped; - imageAvailableSemaphores.reserve( MAX_FRAMES_IN_FLIGHT ); - renderFinishedSemaphores.reserve( MAX_FRAMES_IN_FLIGHT ); - in_flight_fences.reserve( MAX_FRAMES_IN_FLIGHT ); + image_available_sem.reserve( imageCount() ); + render_finished_sem.reserve( imageCount() ); + in_flight_fence.reserve( imageCount() ); images_in_flight.resize( imageCount(), VK_NULL_HANDLE ); vk::SemaphoreCreateInfo semaphoreInfo {}; @@ -433,9 +412,9 @@ namespace fgl::engine { auto& device { Device::getInstance() }; - imageAvailableSemaphores.push_back( device->createSemaphore( semaphoreInfo ) ); - renderFinishedSemaphores.push_back( device->createSemaphore( semaphoreInfo ) ); - in_flight_fences.push_back( device->createFence( fenceInfo ) ); + image_available_sem.push_back( device->createSemaphore( semaphoreInfo ) ); + render_finished_sem.push_back( device->createSemaphore( semaphoreInfo ) ); + in_flight_fence.push_back( device->createFence( fenceInfo ) ); } } @@ -454,13 +433,12 @@ namespace fgl::engine return available_formats[ 0 ]; } - vk::PresentModeKHR SwapChain::chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >& - available_present_modes ) + vk::PresentModeKHR SwapChain::chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >& present_modes ) { ZoneScoped; - for ( const auto& availablePresentMode : available_present_modes ) + for ( const auto& mode : present_modes ) { - switch ( availablePresentMode ) + switch ( mode ) { case vk::PresentModeKHR::eImmediate: std::cout << "Present mode: Immediate" << std::endl; @@ -483,27 +461,20 @@ namespace fgl::engine } } - for ( const auto& present_mode_khr : available_present_modes ) + for ( const auto& mode : present_modes ) { - if ( present_mode_khr == vk::PresentModeKHR::eMailbox ) + if ( mode == vk::PresentModeKHR::eMailbox ) { std::cout << "Present mode: Mailbox: ACTIVE" << std::endl; - return present_mode_khr; + return mode; } } - // for (const auto &availablePresentMode : availablePresentModes) { - // if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) { - // std::cout << "Present mode: Immediate" << std::endl; - // return availablePresentMode; - // } - // } - std::cout << "Present mode: V-Sync: ACTIVE" << std::endl; return vk::PresentModeKHR::eFifo; } - vk::Extent2D SwapChain::chooseSwapExtent( const vk::SurfaceCapabilitiesKHR& capabilities ) + vk::Extent2D SwapChain::chooseSwapExtent( const vk::SurfaceCapabilitiesKHR& capabilities ) const { ZoneScoped; if ( capabilities.currentExtent.width != std::numeric_limits< uint32_t >::max() ) @@ -512,67 +483,64 @@ namespace fgl::engine } else { - vk::Extent2D actualExtent = m_swapchain_extent; - actualExtent.width = std:: - max( capabilities.minImageExtent.width, - std::min( capabilities.maxImageExtent.width, actualExtent.width ) ); - actualExtent.height = std:: - max( capabilities.minImageExtent.height, - std::min( capabilities.maxImageExtent.height, actualExtent.height ) ); + vk::Extent2D actual_extent { m_swapchain_extent }; - return actualExtent; + const auto [ min_height, min_width ] = capabilities.minImageExtent; + const auto [ max_height, max_width ] = capabilities.maxImageExtent; + + actual_extent.width = std::clamp( actual_extent.width, min_width, max_width ); + + actual_extent.height = std::clamp( actual_extent.height, min_height, max_height ); + + return actual_extent; } } - std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > SwapChain:: - createGBufferDescriptors() + std::vector< std::unique_ptr< descriptors::DescriptorSet > > SwapChain::createGBufferDescriptors() { - std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > descriptors {}; + std::vector< std::unique_ptr< descriptors::DescriptorSet > > data; + data.resize( imageCount() ); - for ( FrameIndex frame_idx = 0; frame_idx < SwapChain::MAX_FRAMES_IN_FLIGHT; ++frame_idx ) + for ( PresentIndex i = 0; i < imageCount(); ++i ) { - auto gbuffer_set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) }; + auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) }; - gbuffer_set->setMaxIDX( 2 ); + set->setMaxIDX( 2 ); - gbuffer_set->bindAttachment( - 0, m_gbuffer_attachments.position.view( frame_idx ), vk::ImageLayout::eShaderReadOnlyOptimal ); + set->bindAttachment( 0, gbuffer.position.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - gbuffer_set->bindAttachment( - 1, m_gbuffer_attachments.normal.view( frame_idx ), vk::ImageLayout::eShaderReadOnlyOptimal ); + set->bindAttachment( 1, gbuffer.normal.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - gbuffer_set->bindAttachment( - 2, m_gbuffer_attachments.albedo.view( frame_idx ), vk::ImageLayout::eShaderReadOnlyOptimal ); + set->bindAttachment( 2, gbuffer.albedo.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - gbuffer_set->update(); + set->update(); - descriptors.at( frame_idx ) = std::move( gbuffer_set ); + data[ i ] = std::move( set ); } - return descriptors; + return data; } - std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > SwapChain:: - createGBufferCompositeDescriptors() + std::vector< std::unique_ptr< descriptors::DescriptorSet > > SwapChain::createCompositeDescriptors() { - std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > descriptors {}; + std::vector< std::unique_ptr< descriptors::DescriptorSet > > data; + data.resize( imageCount() ); - for ( FrameIndex frame_idx = 0; frame_idx < SwapChain::MAX_FRAMES_IN_FLIGHT; ++frame_idx ) + for ( PresentIndex i = 0; i < imageCount(); ++i ) { auto composite_set { std::make_unique< descriptors::DescriptorSet >( GBufferCompositeDescriptorSet::createLayout() ) }; - composite_set->setMaxIDX( 0 ); - composite_set->bindAttachment( - 0, m_gbuffer_attachments.composite.view( frame_idx ), vk::ImageLayout::eShaderReadOnlyOptimal ); + composite_set->setMaxIDX( 1 ); + composite_set->bindAttachment( 0, gbuffer.composite.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); composite_set->update(); - m_gbuffer_composite_descriptor_set.at( frame_idx ) = std::move( composite_set ); + data[ i ] = std::move( composite_set ); } - return descriptors; + return data; } vk::Format SwapChain::findDepthFormat() diff --git a/src/engine/rendering/SwapChain.hpp b/src/engine/rendering/SwapChain.hpp index a6377c5..1f7149a 100644 --- a/src/engine/rendering/SwapChain.hpp +++ b/src/engine/rendering/SwapChain.hpp @@ -1,15 +1,13 @@ #pragma once -#include - #include #include #include "Device.hpp" #include "RenderPassBuilder.hpp" #include "engine/FrameInfo.hpp" -#include "engine/rendering/types.hpp" #include "engine/texture/Texture.hpp" +#include "types.hpp" namespace fgl::engine { @@ -17,31 +15,30 @@ namespace fgl::engine { public: - static constexpr FrameIndex MAX_FRAMES_IN_FLIGHT { 2 }; + static constexpr std::uint16_t MAX_FRAMES_IN_FLIGHT { 2 }; private: PhysicalDevice& m_phy_device; - std::shared_ptr< SwapChain > old_swap_chain {}; - SwapChainSupportDetails m_swapchain_support; + SwapChainSupportDetails m_swapchain_details; vk::SurfaceFormatKHR m_surface_format; + vk::PresentModeKHR m_present_mode; + vk::Extent2D m_swapchain_extent; vk::Format m_swap_chain_format; vk::Format m_swap_chain_depth_format; - vk::Extent2D m_swap_chain_extent; - vk::Extent2D m_swapchain_extent; + std::shared_ptr< SwapChain > old_swap_chain; vk::raii::SwapchainKHR m_swapchain; - std::vector< std::shared_ptr< Image > > m_swap_chain_images; + std::vector< Image > m_swap_chain_images; - //! Attachments for the final render target struct { - ColoredPresentAttachment color; // Present attachment + ColoredPresentAttachment color; DepthAttachment depth; - } m_render_attachments; + } render_attachments; struct { @@ -49,80 +46,89 @@ namespace fgl::engine ColorAttachment normal { vk::Format::eR16G16B16A16Sfloat }; ColorAttachment albedo { vk::Format::eR8G8B8A8Unorm }; ColorAttachment composite { vk::Format::eR8G8B8A8Unorm }; - } m_gbuffer_attachments {}; + } gbuffer {}; + + public: + + std::vector< std::unique_ptr< Texture > > g_buffer_position_img {}; + std::vector< std::unique_ptr< Texture > > g_buffer_normal_img {}; + std::vector< std::unique_ptr< Texture > > g_buffer_albedo_img {}; + std::vector< std::unique_ptr< Texture > > g_buffer_composite_img {}; + + private: + + RenderPassBuilder render_pass_builder {}; vk::raii::RenderPass m_render_pass; - std::vector< std::vector< vk::raii::Framebuffer > > m_swap_chain_buffers; + std::vector< vk::raii::Framebuffer > m_swap_chain_buffers; - std::vector< vk::raii::Semaphore > imageAvailableSemaphores {}; - std::vector< vk::raii::Semaphore > renderFinishedSemaphores {}; - std::vector< vk::raii::Fence > in_flight_fences {}; + std::vector< vk::ClearValue > m_clear_values; + + std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_gbuffer_descriptor_set; + + std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_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 {}; - FrameIndex current_frame_index { 0 }; - - 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; + size_t m_current_frame_index { 0 }; void init(); [[nodiscard]] vk::raii::SwapchainKHR createSwapChain(); - [[nodiscard]] std::vector< std::shared_ptr< Image > > createSwapchainImages(); + [[nodiscard]] std::vector< Image > createSwapchainImages(); [[nodiscard]] vk::raii::RenderPass createRenderPass(); - [[nodiscard]] std::vector< std::vector< vk::raii::Framebuffer > > createFramebuffers(); + [[nodiscard]] std::vector< vk::raii::Framebuffer > createFramebuffers(); void createSyncObjects(); - std::vector< vk::ClearValue > populateAttachmentClearValues() + // Helper functions + static vk::SurfaceFormatKHR chooseSwapSurfaceFormat( const std::vector< vk::SurfaceFormatKHR >& + available_formats ); + static vk::PresentModeKHR chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >& present_modes ); + vk::Extent2D chooseSwapExtent( const vk::SurfaceCapabilitiesKHR& capabilities ) const; + + template < is_attachment... Attachments > + static std::vector< vk::ImageView > getViewsForFrame( const std::uint8_t frame_idx, Attachments... attachments ) { - return 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 ); + std::vector< vk::ImageView > view {}; + view.resize( sizeof...( Attachments ) ); + + ( ( view[ attachments.getIndex() ] = *attachments.getView( frame_idx ) ), ... ); + + return view; } template < is_attachment... Attachments > - std::vector< vk::ClearValue > populateAttachmentClearValues( Attachments&... attachments ) + static std::vector< vk::ClearValue > gatherClearValues( Attachments... attachments ) { - std::vector< vk::ClearValue > values {}; + std::vector< vk::ClearValue > clear_values {}; + clear_values.resize( sizeof...( Attachments ) ); - values.resize( sizeof...( Attachments ) ); - ( ( values[ attachments.getIndex() ] = attachments.m_clear_value ), ... ); + ( ( clear_values[ attachments.getIndex() ] = attachments.m_clear_value ), ... ); - return values; + return clear_values; } - // Helper functions - 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 > - createGBufferDescriptors(); - - std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > - createGBufferCompositeDescriptors(); + std::vector< std::unique_ptr< descriptors::DescriptorSet > > createGBufferDescriptors(); + std::vector< std::unique_ptr< descriptors::DescriptorSet > > createCompositeDescriptors(); public: std::vector< vk::ClearValue > getClearValues() const { return m_clear_values; } - descriptors::DescriptorSet& getGBufferDescriptor( std::uint16_t frame_idx ) const + descriptors::DescriptorSet& getGBufferDescriptor( PresentIndex frame_idx ) const { - assert( frame_idx < SwapChain::MAX_FRAMES_IN_FLIGHT && "Frame index out of range" ); + assert( frame_idx < imageCount() && "Frame index out of range" ); + assert( m_gbuffer_descriptor_set.size() > 0 && "GBuffer descriptor set not initialized" ); return *m_gbuffer_descriptor_set[ frame_idx ]; } - descriptors::DescriptorSet& getGBufferCompositeDescriptor( uint16_t frame_idx ) const + descriptors::DescriptorSet& getGBufferCompositeDescriptor( PresentIndex frame_idx ) const { - assert( frame_idx < SwapChain::MAX_FRAMES_IN_FLIGHT && "Frame index out of range" ); - return *m_gbuffer_composite_descriptor_set[ frame_idx ]; + assert( frame_idx < imageCount() && "Frame index out of range" ); + assert( m_composite_descriptor_set.size() > 0 && "GBuffer descriptor set not initialized" ); + return *m_composite_descriptor_set[ frame_idx ]; } SwapChain( vk::Extent2D windowExtent, PhysicalDevice& phy_dev ); @@ -131,33 +137,22 @@ namespace fgl::engine SwapChain( const SwapChain& ) = delete; SwapChain& operator=( const SwapChain& ) = delete; - vk::raii::Framebuffer& getFrameBuffer( const FrameIndex frame_index, const std::uint16_t present_idx ); + vk::raii::Framebuffer& getFrameBuffer( const PresentIndex present_index ) + { + return m_swap_chain_buffers[ static_cast< std::size_t >( present_index ) ]; + } vk::raii::RenderPass& getRenderPass() { return m_render_pass; } - std::uint16_t imageCount() const - { - assert( m_swap_chain_images.size() > 0 ); - return m_swap_chain_images.size(); - } + PresentIndex imageCount() const { return static_cast< std::uint16_t >( m_swap_chain_images.size() ); } - vk::Format getSwapChainImageFormat() const - { - assert( m_swap_chain_format != vk::Format::eUndefined ); - return m_swap_chain_format; - } + vk::Format getSwapChainImageFormat() const { return m_swap_chain_format; } - vk::Extent2D getSwapChainExtent() const { return m_swap_chain_extent; } + vk::Extent2D getSwapChainExtent() const { return m_swapchain_extent; } - uint32_t width() const - { - return m_swap_chain_extent.width; - } + uint32_t width() const { return m_swapchain_extent.width; } - uint32_t height() const - { - return m_swap_chain_extent.height; - } + uint32_t height() const { return m_swapchain_extent.height; } bool compareSwapFormats( const SwapChain& other ) const { @@ -167,15 +162,14 @@ namespace fgl::engine float extentAspectRatio() const { - return static_cast< float >( m_swap_chain_extent.width ) - / static_cast< float >( m_swap_chain_extent.height ); + return static_cast< float >( m_swapchain_extent.width ) / static_cast< float >( m_swapchain_extent.height ); } - vk::Format findDepthFormat(); + static vk::Format findDepthFormat(); - [[nodiscard]] std::pair< vk::Result, std::uint32_t > acquireNextImage(); + [[nodiscard]] std::pair< vk::Result, PresentIndex > acquireNextImage(); [[nodiscard]] vk::Result - submitCommandBuffers( const vk::raii::CommandBuffer& buffers, PresentIndex current_present_index ); + submitCommandBuffers( const vk::raii::CommandBuffer& buffers, PresentIndex present_index ); }; } // namespace fgl::engine diff --git a/src/engine/rendering/types.hpp b/src/engine/rendering/types.hpp index de13525..5f919dc 100644 --- a/src/engine/rendering/types.hpp +++ b/src/engine/rendering/types.hpp @@ -1,11 +1,13 @@ // -// Created by kj16609 on 7/10/24. +// Created by kj16609 on 7/11/24. // #pragma once +#include + namespace fgl::engine { - using FrameIndex = std::uint16_t; using PresentIndex = std::uint16_t; -} // namespace fgl::engine + using FrameIndex = std::uint16_t; +} diff --git a/src/engine/systems/GuiSystem.cpp b/src/engine/systems/GuiSystem.cpp index c084789..256a6b0 100644 --- a/src/engine/systems/GuiSystem.cpp +++ b/src/engine/systems/GuiSystem.cpp @@ -28,18 +28,17 @@ namespace fgl::engine command_buffer.nextSubpass( vk::SubpassContents::eInline ); + m_pipeline->bind( command_buffer ); + m_pipeline ->bindDescriptor( command_buffer, GBufferCompositeDescriptorSet::m_set_idx, info.gbuffer_composite_set ); - m_pipeline->bind( command_buffer ); - return command_buffer; } void GuiSystem::pass( FrameInfo& info ) { auto& command_buffer { setupSystem( info ) }; - TracyVkZone( info.tracy_ctx, *command_buffer, "Debug GUI Pass" ); command_buffer.draw( 3, 1, 0, 0 );