From 2e9e08a1854597b06f8d2c7c08d5c978e7cfa47d Mon Sep 17 00:00:00 2001 From: kj16609 Date: Mon, 20 Jan 2025 09:58:33 -0500 Subject: [PATCH] Finish dynamic rendering changes --- CMakeLists.txt | 2 +- src/editor/CMakeLists.txt | 4 +- src/editor/src/gui/core.cpp | 14 +- src/editor/src/gui/preview.cpp | 2 +- src/engine/EngineContext.hpp | 2 +- src/engine/FrameInfo.hpp | 4 +- src/engine/assets/image/Image.cpp | 8 +- src/engine/assets/image/Image.hpp | 10 +- src/engine/assets/image/ImageHandle.cpp | 14 + src/engine/assets/image/ImageHandle.hpp | 13 +- src/engine/camera/Camera.cpp | 10 +- src/engine/camera/Camera.hpp | 2 + src/engine/camera/CompositeSwapchain.cpp | 24 +- src/engine/camera/CompositeSwapchain.hpp | 4 + src/engine/camera/GBufferCompositor.cpp | 2 + src/engine/camera/GBufferSwapchain.cpp | 16 +- src/engine/camera/GBufferSwapchain.hpp | 2 +- src/engine/concepts/is_attachment.hpp | 24 +- src/engine/debug/timing/FlameGraph.cpp | 8 +- src/engine/descriptors/DescriptorSet.cpp | 4 +- .../{SwapChain.cpp => PresentSwapChain.cpp} | 272 +++++++++--------- src/engine/rendering/PresentSwapChain.hpp | 114 ++++++++ src/engine/rendering/QueuePool.cpp | 1 + src/engine/rendering/Renderer.cpp | 31 +- src/engine/rendering/Renderer.hpp | 8 +- src/engine/rendering/RenderingFormats.cpp | 19 ++ src/engine/rendering/RenderingFormats.hpp | 1 + src/engine/rendering/SwapChain.hpp | 115 -------- src/engine/rendering/pipelines/Attachment.hpp | 49 ++-- src/engine/rendering/pipelines/Shader.cpp | 3 +- .../pipelines/v2/PipelineBuilder.cpp | 2 +- src/engine/systems/composition/GuiSystem.cpp | 5 +- src/engine/systems/composition/GuiSystem.hpp | 5 +- .../systems/render/EntityRendererSystem.hpp | 2 +- src/engine/systems/render/LineDrawer.hpp | 2 +- 35 files changed, 434 insertions(+), 364 deletions(-) rename src/engine/rendering/{SwapChain.cpp => PresentSwapChain.cpp} (59%) create mode 100644 src/engine/rendering/PresentSwapChain.hpp delete mode 100644 src/engine/rendering/SwapChain.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2742de0..b0bce2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ PreSetup() PostSetup() -file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/data) +#file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/data) #Enable cmake_modules list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") diff --git a/src/editor/CMakeLists.txt b/src/editor/CMakeLists.txt index a571f47..05b285c 100644 --- a/src/editor/CMakeLists.txt +++ b/src/editor/CMakeLists.txt @@ -9,9 +9,9 @@ file(GLOB_RECURSE SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/**.hpp" ) -add_executable(TitorEditor ${SOURCE_FILES}) +AddFGLExecutable(TitorEditor ${CMAKE_CURRENT_SOURCE_DIR}/src) + target_link_libraries(TitorEditor PRIVATE FGLEngine) -target_include_directories(TitorEditor PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) target_compile_definitions(TitorEditor PUBLIC TITOR_EDITOR) target_compile_features(TitorEditor PRIVATE cxx_std_23) target_link_libraries(TitorEditor PRIVATE glfw ImGui) diff --git a/src/editor/src/gui/core.cpp b/src/editor/src/gui/core.cpp index a598bc1..a7cc603 100644 --- a/src/editor/src/gui/core.cpp +++ b/src/editor/src/gui/core.cpp @@ -24,6 +24,7 @@ #include "engine/rendering/Renderer.hpp" #include "engine/tree/octtree/OctTreeNode.hpp" #include "gui_window_names.hpp" +#include "rendering/RenderingFormats.hpp" #include "safe_include.hpp" namespace fgl::engine::gui @@ -44,6 +45,13 @@ namespace fgl::engine::gui Device& device { Device::getInstance() }; + vk::PipelineRenderingCreateInfo pipeline_info {}; + + const std::vector< vk::Format > color_formats { pickPresentFormat() }; + + pipeline_info.setColorAttachmentFormats( color_formats ); + pipeline_info.setDepthAttachmentFormat( pickDepthFormat() ); + ImGui_ImplGlfw_InitForVulkan( window.window(), true ); ImGui_ImplVulkan_InitInfo init_info { .Instance = device.instance(), @@ -52,7 +60,7 @@ namespace fgl::engine::gui .QueueFamily = device.phyDevice().queueInfo().getIndex( vk::QueueFlagBits::eGraphics ), .Queue = *device.graphicsQueue(), .DescriptorPool = *DescriptorPool::getInstance().getPool(), - .RenderPass = *renderer.getSwapChainRenderPass(), + .RenderPass = VK_NULL_HANDLE, .MinImageCount = 2, .ImageCount = 2, .MSAASamples = VK_SAMPLE_COUNT_1_BIT, @@ -60,8 +68,8 @@ namespace fgl::engine::gui .PipelineCache = VK_NULL_HANDLE, .Subpass = 0, - .UseDynamicRendering = VK_FALSE, - .PipelineRenderingCreateInfo = {}, + .UseDynamicRendering = VK_TRUE, + .PipelineRenderingCreateInfo = pipeline_info, .Allocator = VK_NULL_HANDLE, .CheckVkResultFn = VK_NULL_HANDLE, diff --git a/src/editor/src/gui/preview.cpp b/src/editor/src/gui/preview.cpp index 5fc7c13..4eb8b32 100644 --- a/src/editor/src/gui/preview.cpp +++ b/src/editor/src/gui/preview.cpp @@ -12,7 +12,7 @@ #include "engine/filesystem/scanner/FileScanner.hpp" #include "engine/filesystem/types.hpp" #include "engine/gameobjects/components/ModelComponent.hpp" -#include "engine/rendering/SwapChain.hpp" +#include "engine/rendering/PresentSwapChain.hpp" #include "engine/tree/octtree/OctTreeNode.hpp" #include "safe_include.hpp" diff --git a/src/engine/EngineContext.hpp b/src/engine/EngineContext.hpp index e3a6a82..e2b2e32 100644 --- a/src/engine/EngineContext.hpp +++ b/src/engine/EngineContext.hpp @@ -56,7 +56,7 @@ namespace fgl::engine vk::MemoryPropertyFlagBits::eDeviceLocal ) }; // SubPass 0 - GuiSystem m_gui_system { m_renderer.getSwapChainRenderPass() }; + GuiSystem m_gui_system {}; // Functions BEFORE a frame is started std::vector< FrameHookFunc > pre_frame_hooks {}; diff --git a/src/engine/FrameInfo.hpp b/src/engine/FrameInfo.hpp index 3ed3202..5bcb459 100644 --- a/src/engine/FrameInfo.hpp +++ b/src/engine/FrameInfo.hpp @@ -26,7 +26,7 @@ namespace fgl::engine class DescriptorSet; } - class SwapChain; + class PresentSwapChain; class Camera; struct PointLight @@ -96,7 +96,7 @@ namespace fgl::engine descriptors::DescriptorSet& getGBufferDescriptor() const; descriptors::DescriptorSet& getCameraDescriptor() const; - SwapChain& swap_chain; + PresentSwapChain& swap_chain; std::vector< std::vector< GameObject >* > in_view_leafs {}; diff --git a/src/engine/assets/image/Image.cpp b/src/engine/assets/image/Image.cpp index 6b76ce5..c0c58e3 100644 --- a/src/engine/assets/image/Image.cpp +++ b/src/engine/assets/image/Image.cpp @@ -32,7 +32,6 @@ namespace fgl::engine break; case vk::ImageLayout::eColorAttachmentOptimal: return vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite; - case vk::ImageLayout::eDepthStencilAttachmentOptimal: break; case vk::ImageLayout::eDepthStencilReadOnlyOptimal: break; @@ -48,13 +47,15 @@ namespace fgl::engine break; case vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal: break; + case vk::ImageLayout::eStencilAttachmentOptimal: + break; + case vk::ImageLayout::eDepthStencilAttachmentOptimal: + [[fallthrough]]; case vk::ImageLayout::eDepthReadOnlyOptimal: [[fallthrough]]; case vk::ImageLayout::eDepthAttachmentOptimal: return vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite; - case vk::ImageLayout::eStencilAttachmentOptimal: - break; case vk::ImageLayout::eStencilReadOnlyOptimal: break; case vk::ImageLayout::eReadOnlyOptimal: @@ -186,6 +187,7 @@ namespace fgl::engine vk::ImageMemoryBarrier Image::transitionTo( const vk::ImageLayout old_layout, const vk::ImageLayout new_layout, const vk::ImageAspectFlags aspect ) { + assert( m_handle->m_name.empty() == false && "Image name not assigned" ); const vk::ImageSubresourceRange subresource { aspect, 0, 1, 0, 1 }; const vk::ImageMemoryBarrier barrier { transitionTo( old_layout, new_layout, subresource ) }; diff --git a/src/engine/assets/image/Image.hpp b/src/engine/assets/image/Image.hpp index cffe7bf..571db02 100644 --- a/src/engine/assets/image/Image.hpp +++ b/src/engine/assets/image/Image.hpp @@ -4,9 +4,9 @@ #pragma once -#include +#include -#include "engine/assets/image/ImageHandle.hpp" +#include namespace fgl::engine { @@ -16,6 +16,7 @@ namespace fgl::engine } class ImageView; + class ImageHandle; class Image { @@ -58,9 +59,10 @@ namespace fgl::engine vk::ImageMemoryBarrier transitionTo( vk::ImageLayout old_layout, vk::ImageLayout new_layout, const vk::ImageSubresourceRange& range ) const; - vk::ImageMemoryBarrier transitionTo( vk::ImageLayout old_layout, vk::ImageLayout new_layout, vk::ImageAspectFlags aspect ); + vk::ImageMemoryBarrier + transitionTo( vk::ImageLayout old_layout, vk::ImageLayout new_layout, vk::ImageAspectFlags aspect ); - inline vk::ImageMemoryBarrier transitionColorTo(vk::ImageLayout old_layout, vk::ImageLayout new_layout) + inline vk::ImageMemoryBarrier transitionColorTo( vk::ImageLayout old_layout, vk::ImageLayout new_layout ) { return transitionTo( old_layout, new_layout, vk::ImageAspectFlagBits::eColor ); } diff --git a/src/engine/assets/image/ImageHandle.cpp b/src/engine/assets/image/ImageHandle.cpp index 6c51015..4bbedf5 100644 --- a/src/engine/assets/image/ImageHandle.cpp +++ b/src/engine/assets/image/ImageHandle.cpp @@ -95,10 +95,24 @@ namespace fgl::engine { vk::DebugUtilsObjectNameInfoEXT info {}; + log::debug( "Setting name of image to {}", str ); + m_name = str; + info.objectType = vk::ObjectType::eImage; info.pObjectName = str.c_str(); info.setObjectHandle( reinterpret_cast< uint64_t >( getVkImage() ) ); Device::getInstance().setDebugUtilsObjectName( info ); } + + VkImage ImageHandle::operator*() + { + ZoneScoped; + if ( std::holds_alternative< vk::raii::Image >( m_image ) ) + { + return *std::get< vk::raii::Image >( m_image ); + } + + return std::get< vk::Image >( m_image ); + } } // namespace fgl::engine diff --git a/src/engine/assets/image/ImageHandle.hpp b/src/engine/assets/image/ImageHandle.hpp index 0a30d34..8f5b5c4 100644 --- a/src/engine/assets/image/ImageHandle.hpp +++ b/src/engine/assets/image/ImageHandle.hpp @@ -32,6 +32,8 @@ namespace fgl::engine // Because of the way the swapchain works we need to be able to storage a `VkImage` handle. std::variant< vk::raii::Image, vk::Image > m_image; + std::string m_name { "" }; + bool m_staged { false }; friend class ImageView; @@ -52,16 +54,7 @@ namespace fgl::engine void setName( std::string str ); - VkImage operator*() - { - ZoneScoped; - if ( std::holds_alternative< vk::raii::Image >( m_image ) ) - { - return *std::get< vk::raii::Image >( m_image ); - } - - return std::get< vk::Image >( m_image ); - } + VkImage operator*(); VkImage getVkImage() { return **this; } diff --git a/src/engine/camera/Camera.cpp b/src/engine/camera/Camera.cpp index f0e481b..29748d5 100644 --- a/src/engine/camera/Camera.cpp +++ b/src/engine/camera/Camera.cpp @@ -133,6 +133,9 @@ namespace fgl::engine { this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE ); + m_old_composite_swapchain = std::move( m_composite_swapchain ); + m_old_gbuffer_swapchain = std::move( m_gbuffer_swapchain ); + m_composite_swapchain = std::make_unique< CompositeSwapchain >( extent ); m_gbuffer_swapchain = std::make_unique< GBufferSwapchain >( extent ); } @@ -326,18 +329,19 @@ namespace fgl::engine return camera_descriptor_set; } - Camera::Camera( const vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer ) : + Camera::Camera( + const vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer ) : m_target_extent( extent ), m_composite_swapchain( std::make_unique< CompositeSwapchain >( m_target_extent ) ), m_gbuffer_swapchain( std::make_unique< GBufferSwapchain >( m_target_extent ) ), m_camera_renderer( renderer ), - m_camera_frame_info( buffer, SwapChain::MAX_FRAMES_IN_FLIGHT ) + m_camera_frame_info( buffer, PresentSwapChain::MAX_FRAMES_IN_FLIGHT ) { FGL_ASSERT( renderer, "Camera renderer is null" ); this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE ); this->setView( WorldCoordinate( constants::CENTER ), Rotation( 0.0f, 0.0f, 0.0f ) ); - for ( std::uint8_t i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i ) + for ( std::uint8_t i = 0; i < PresentSwapChain::MAX_FRAMES_IN_FLIGHT; ++i ) { auto set { camera_descriptor_set.create() }; set->bindUniformBuffer( 0, m_camera_frame_info[ i ] ); diff --git a/src/engine/camera/Camera.hpp b/src/engine/camera/Camera.hpp index 1314b4e..41c0f41 100644 --- a/src/engine/camera/Camera.hpp +++ b/src/engine/camera/Camera.hpp @@ -51,7 +51,9 @@ namespace fgl::engine vk::Extent2D m_target_extent; + std::unique_ptr< CompositeSwapchain > m_old_composite_swapchain; std::unique_ptr< CompositeSwapchain > m_composite_swapchain; + std::unique_ptr< GBufferSwapchain > m_old_gbuffer_swapchain; std::unique_ptr< GBufferSwapchain > m_gbuffer_swapchain; std::shared_ptr< GBufferRenderer > m_camera_renderer; diff --git a/src/engine/camera/CompositeSwapchain.cpp b/src/engine/camera/CompositeSwapchain.cpp index 301df29..74aa859 100644 --- a/src/engine/camera/CompositeSwapchain.cpp +++ b/src/engine/camera/CompositeSwapchain.cpp @@ -3,7 +3,7 @@ // #include "CompositeSwapchain.hpp" -#include "engine/rendering/SwapChain.hpp" +#include "engine/rendering/PresentSwapChain.hpp" #include "engine/rendering/pipelines/Attachment.hpp" namespace fgl::engine @@ -35,6 +35,23 @@ namespace fgl::engine return; } case FINAL: + { + const std::vector< vk::ImageMemoryBarrier > barriers { + m_buffer.m_target.getImage( index ).transitionColorTo( + vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ), + }; + + command_buffer.pipelineBarrier( + vk::PipelineStageFlagBits::eColorAttachmentOutput, + vk::PipelineStageFlagBits::eFragmentShader, + vk::DependencyFlags( 0 ), + {}, + {}, + barriers ); + + return; + } + case FINAL_PRESENT: { const std::vector< vk::ImageMemoryBarrier > barriers { m_buffer.m_target.getImage( index ).transitionColorTo( @@ -52,6 +69,8 @@ namespace fgl::engine return; } } + + FGL_UNREACHABLE(); } vk::RenderingInfo CompositeSwapchain::getRenderingInfo( const FrameIndex index ) @@ -75,9 +94,10 @@ namespace fgl::engine CompositeSwapchain::CompositeSwapchain( vk::Extent2D extent ) : m_extent( extent ) { - constexpr auto image_count { SwapChain::MAX_FRAMES_IN_FLIGHT }; + constexpr auto image_count { PresentSwapChain::MAX_FRAMES_IN_FLIGHT }; m_buffer.m_target.createResources( image_count, m_extent, vk::ImageUsageFlagBits::eTransferSrc ); + m_buffer.m_target.setName( "CompositeSwapchain::m_target" ); for ( const auto& image : m_buffer.m_target.m_attachment_resources.m_images ) { diff --git a/src/engine/camera/CompositeSwapchain.hpp b/src/engine/camera/CompositeSwapchain.hpp index f1b54bc..662044b 100644 --- a/src/engine/camera/CompositeSwapchain.hpp +++ b/src/engine/camera/CompositeSwapchain.hpp @@ -2,6 +2,9 @@ // Created by kj16609 on 1/13/25. // #pragma once +#include + +#include "FGL_DEFINES.hpp" #include "engine/rendering/RenderingFormats.hpp" #include "engine/rendering/pipelines/Attachment.hpp" @@ -29,6 +32,7 @@ namespace fgl::engine { INITAL, FINAL, + FINAL_PRESENT, }; void transitionImages( vk::raii::CommandBuffer& command_buffer, StageID stage_id, FrameIndex index ); diff --git a/src/engine/camera/GBufferCompositor.cpp b/src/engine/camera/GBufferCompositor.cpp index 5171f47..d35874d 100644 --- a/src/engine/camera/GBufferCompositor.cpp +++ b/src/engine/camera/GBufferCompositor.cpp @@ -94,6 +94,8 @@ namespace fgl::engine command_buffer.draw( 3, 1, 0, 0 ); endPass( command_buffer ); + + composite_swapchain.transitionImages( command_buffer, CompositeSwapchain::FINAL, frame_index ); } } // namespace fgl::engine diff --git a/src/engine/camera/GBufferSwapchain.cpp b/src/engine/camera/GBufferSwapchain.cpp index b2b9515..5dffa81 100644 --- a/src/engine/camera/GBufferSwapchain.cpp +++ b/src/engine/camera/GBufferSwapchain.cpp @@ -12,22 +12,22 @@ namespace fgl::engine std::vector< std::unique_ptr< descriptors::DescriptorSet > > GBufferSwapchain::createGBufferDescriptors() { std::vector< std::unique_ptr< descriptors::DescriptorSet > > data {}; - data.resize( SwapChain::MAX_FRAMES_IN_FLIGHT ); + data.resize( PresentSwapChain::MAX_FRAMES_IN_FLIGHT ); - for ( PresentIndex i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i ) + for ( PresentIndex i = 0; i < PresentSwapChain::MAX_FRAMES_IN_FLIGHT; ++i ) { //auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) }; auto set { gbuffer_set.create() }; - set->bindAttachment( 0, m_gbuffer.m_color.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR ); + set->bindAttachment( 0, m_gbuffer.m_color.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - set->bindAttachment( 1, m_gbuffer.m_position.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR ); + set->bindAttachment( 1, m_gbuffer.m_position.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - set->bindAttachment( 2, m_gbuffer.m_normal.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR ); + set->bindAttachment( 2, m_gbuffer.m_normal.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - set->bindAttachment( 3, m_gbuffer.m_metallic.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR ); + set->bindAttachment( 3, m_gbuffer.m_metallic.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - set->bindAttachment( 4, m_gbuffer.m_emissive.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR ); + set->bindAttachment( 4, m_gbuffer.m_emissive.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); set->update(); @@ -157,7 +157,7 @@ namespace fgl::engine GBufferSwapchain::GBufferSwapchain( const vk::Extent2D extent ) : m_extent( extent ) // m_gbuffer_descriptor_set( createGBufferDescriptors() ) { - constexpr auto image_count { SwapChain::MAX_FRAMES_IN_FLIGHT }; + constexpr auto image_count { PresentSwapChain::MAX_FRAMES_IN_FLIGHT }; m_gbuffer.m_color.createResources( image_count, m_extent ); m_gbuffer.m_position.createResources( image_count, m_extent ); diff --git a/src/engine/camera/GBufferSwapchain.hpp b/src/engine/camera/GBufferSwapchain.hpp index 46590b8..957f802 100644 --- a/src/engine/camera/GBufferSwapchain.hpp +++ b/src/engine/camera/GBufferSwapchain.hpp @@ -5,8 +5,8 @@ #pragma once #include "engine/descriptors/DescriptorSet.hpp" +#include "engine/rendering/PresentSwapChain.hpp" #include "engine/rendering/RenderingFormats.hpp" -#include "engine/rendering/SwapChain.hpp" #include "engine/rendering/pipelines/Attachment.hpp" namespace fgl::engine diff --git a/src/engine/concepts/is_attachment.hpp b/src/engine/concepts/is_attachment.hpp index cc17270..6e8314f 100644 --- a/src/engine/concepts/is_attachment.hpp +++ b/src/engine/concepts/is_attachment.hpp @@ -16,24 +16,12 @@ namespace fgl::engine template < typename T > concept is_attachment = requires( T a ) { - { - a.desc() - } -> std::same_as< vk::AttachmentDescription& >; - { - a.m_index - } -> std::same_as< const std::uint32_t& >; - { - a.attachImageView( std::declval< std::uint16_t >(), std::declval< std::shared_ptr< ImageView > >() ) - }; - { - 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 - } -> std::same_as< vk::ClearValue& >; + { a.desc() } -> std::same_as< vk::AttachmentDescription& >; + { a.m_index } -> std::same_as< const std::uint32_t& >; + { a.attachImageView( std::declval< std::uint16_t >(), std::declval< std::shared_ptr< ImageView > >() ) }; + { a.linkImage( std::declval< std::uint16_t >(), std::declval< std::shared_ptr< Image >& >() ) }; + { a.getView( std::declval< std::uint8_t >() ) } -> std::same_as< ImageView& >; + { a.m_clear_value } -> std::same_as< vk::ClearValue& >; }; } // namespace fgl::engine diff --git a/src/engine/debug/timing/FlameGraph.cpp b/src/engine/debug/timing/FlameGraph.cpp index 5fc0b30..fb857e7 100644 --- a/src/engine/debug/timing/FlameGraph.cpp +++ b/src/engine/debug/timing/FlameGraph.cpp @@ -21,18 +21,18 @@ namespace fgl::engine::debug struct Node { - std::string_view m_name { "" }; + std::string_view m_name; ProfilingClock::time_point m_start {}; ProfilingClock::time_point m_end {}; std::vector< Node > m_children {}; Node* m_parent { nullptr }; void drawImGui() const; - using duration = ProfilingClock::duration; + using Duration = ProfilingClock::duration; - duration getDuration() const { return m_end - m_start; } + Duration getDuration() const { return m_end - m_start; } - duration getTotalTime() const + Duration getTotalTime() const { if ( m_parent != nullptr ) return m_parent->getTotalTime(); diff --git a/src/engine/descriptors/DescriptorSet.cpp b/src/engine/descriptors/DescriptorSet.cpp index 1cfc67d..b8a8a2f 100644 --- a/src/engine/descriptors/DescriptorSet.cpp +++ b/src/engine/descriptors/DescriptorSet.cpp @@ -13,7 +13,7 @@ #include "engine/assets/image/ImageView.hpp" #include "engine/assets/texture/Texture.hpp" #include "engine/memory/buffers/BufferSuballocation.hpp" -#include "engine/rendering/SwapChain.hpp" +#include "engine/rendering/PresentSwapChain.hpp" namespace fgl::engine::descriptors { @@ -214,7 +214,7 @@ namespace fgl::engine::descriptors { auto& [ counter, set ] = *itter; // Prevent deleting a descriptor until we are sure it's been here long enough - if ( counter > SwapChain::MAX_FRAMES_IN_FLIGHT + 1 ) + if ( counter > PresentSwapChain::MAX_FRAMES_IN_FLIGHT + 1 ) { itter = QUEUE.erase( itter ); } diff --git a/src/engine/rendering/SwapChain.cpp b/src/engine/rendering/PresentSwapChain.cpp similarity index 59% rename from src/engine/rendering/SwapChain.cpp rename to src/engine/rendering/PresentSwapChain.cpp index 28b1705..82618d5 100644 --- a/src/engine/rendering/SwapChain.cpp +++ b/src/engine/rendering/PresentSwapChain.cpp @@ -1,4 +1,4 @@ -#include "SwapChain.hpp" +#include "PresentSwapChain.hpp" #include #include @@ -15,7 +15,7 @@ namespace fgl::engine { - SwapChain::SwapChain( const vk::Extent2D extent, PhysicalDevice& phy_device ) : + PresentSwapChain::PresentSwapChain( const vk::Extent2D extent, PhysicalDevice& phy_device ) : m_phy_device( phy_device ), m_swapchain_details( Device::getInstance().getSwapChainSupport() ), m_surface_format( chooseSwapSurfaceFormat( m_swapchain_details.formats ) ), @@ -23,21 +23,26 @@ namespace fgl::engine m_swapchain_extent( extent ), m_swap_chain_format( m_surface_format.format ), m_swap_chain_depth_format( pickDepthFormat() ), - old_swap_chain( nullptr ), + m_old_swap_chain( nullptr ), m_swapchain( createSwapChain() ), m_swap_chain_images( createSwapchainImages() ), - render_attachments( getSwapChainImageFormat(), pickDepthFormat() ), - m_render_pass( createRenderPass() ), - m_swap_chain_buffers( createFramebuffers() ), + m_render_attachments( m_swap_chain_format, pickDepthFormat() ), // m_input_descriptors( createInputDescriptors() ), m_clear_values( // gatherClearValues( render_attachments.color, render_attachments.depth, render_attachments.input_color ) ) - gatherClearValues( render_attachments.color, render_attachments.depth ) ) + gatherClearValues( m_render_attachments.m_color, m_render_attachments.m_depth ) ) { init(); + + m_render_attachments.m_color.linkImages( m_swap_chain_images ); + m_render_attachments.m_color.setName( "PresetnSwapChain::color" ); + + m_render_attachments.m_depth.createResources( imageCount(), getSwapChainExtent() ); + m_render_attachments.m_depth.setName( "PresentSwapChain::Depth" ); + m_render_attachments.m_depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) ); } - SwapChain::SwapChain( const vk::Extent2D extent, std::shared_ptr< SwapChain > previous ) : + PresentSwapChain::PresentSwapChain( const vk::Extent2D extent, std::shared_ptr< PresentSwapChain > previous ) : m_phy_device( previous->m_phy_device ), m_swapchain_details( Device::getInstance().getSwapChainSupport() ), m_surface_format( chooseSwapSurfaceFormat( m_swapchain_details.formats ) ), @@ -45,22 +50,28 @@ namespace fgl::engine m_swapchain_extent( extent ), m_swap_chain_format( m_surface_format.format ), m_swap_chain_depth_format( pickDepthFormat() ), - old_swap_chain( previous ), + m_old_swap_chain( previous ), m_swapchain( createSwapChain() ), m_swap_chain_images( createSwapchainImages() ), - render_attachments( getSwapChainImageFormat(), m_swap_chain_depth_format ), - m_render_pass( createRenderPass() ), - m_swap_chain_buffers( createFramebuffers() ), + m_render_attachments( m_swap_chain_format, m_swap_chain_depth_format ), // m_input_descriptors( createInputDescriptors() ), m_clear_values( // gatherClearValues( render_attachments.color, render_attachments.depth, render_attachments.input_color ) ) - gatherClearValues( render_attachments.color, render_attachments.depth ) ) + gatherClearValues( m_render_attachments.m_color, m_render_attachments.m_depth ) ) { init(); - old_swap_chain.reset(); + + m_render_attachments.m_color.linkImages( m_swap_chain_images ); + m_render_attachments.m_color.setName( "PresetnSwapChain::color" ); + + m_render_attachments.m_depth.createResources( imageCount(), getSwapChainExtent() ); + m_render_attachments.m_depth.setName( "PresentSwapChain::Depth" ); + m_render_attachments.m_depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) ); + + m_old_swap_chain.reset(); } - std::vector< std::unique_ptr< descriptors::DescriptorSet > > SwapChain::createInputDescriptors() + std::vector< std::unique_ptr< descriptors::DescriptorSet > > PresentSwapChain::createInputDescriptors() { std::vector< std::unique_ptr< descriptors::DescriptorSet > > data {}; data.resize( imageCount() ); @@ -81,18 +92,18 @@ namespace fgl::engine return data; } - void SwapChain::init() + void PresentSwapChain::init() { createSyncObjects(); // render_attachments.input_color.setName( "Input Color" ); } - std::pair< vk::Result, PresentIndex > SwapChain::acquireNextImage() + std::pair< vk::Result, PresentIndex > PresentSwapChain::acquireNextImage() { ZoneScoped; - std::vector< vk::Fence > fences { in_flight_fence[ m_current_frame_index ] }; + std::vector< vk::Fence > fences { m_in_flight_fence[ m_current_frame_index ] }; if ( Device::getInstance().device().waitForFences( fences, VK_TRUE, std::numeric_limits< uint64_t >::max() ) != vk::Result::eSuccess ) @@ -100,20 +111,20 @@ namespace fgl::engine auto result { m_swapchain.acquireNextImage( std::numeric_limits< uint64_t >::max(), - image_available_sem[ m_current_frame_index ] // must be a not signaled semaphore + m_image_available_sem[ m_current_frame_index ] // must be a not signaled semaphore ) }; return result; } - vk::Result SwapChain:: + vk::Result PresentSwapChain:: submitCommandBuffers( const vk::raii::CommandBuffer& buffers, const PresentIndex present_index ) { ZoneScoped; - images_in_flight[ present_index ] = in_flight_fence[ m_current_frame_index ]; + m_images_in_flight[ present_index ] = m_in_flight_fence[ m_current_frame_index ]; - std::vector< vk::Fence > fences { images_in_flight[ present_index ] }; + std::vector< vk::Fence > fences { m_images_in_flight[ present_index ] }; if ( Device::getInstance().device().waitForFences( fences, VK_TRUE, std::numeric_limits< uint64_t >::max() ) != vk::Result::eSuccess ) @@ -121,7 +132,7 @@ namespace fgl::engine vk::SubmitInfo m_submit_info {}; - std::vector< vk::Semaphore > wait_sems { image_available_sem[ m_current_frame_index ], + std::vector< vk::Semaphore > wait_sems { m_image_available_sem[ m_current_frame_index ], memory::TransferManager::getInstance().getFinishedSem() }; std::vector< vk::PipelineStageFlags > wait_stages { vk::PipelineStageFlagBits::eColorAttachmentOutput, @@ -133,14 +144,14 @@ namespace fgl::engine m_submit_info.commandBufferCount = 1; m_submit_info.pCommandBuffers = &( *buffers ); - std::vector< vk::Semaphore > signaled_semaphores { render_finished_sem[ m_current_frame_index ] }; + std::vector< vk::Semaphore > signaled_semaphores { m_render_finished_sem[ m_current_frame_index ] }; m_submit_info.setSignalSemaphores( signaled_semaphores ); Device::getInstance().device().resetFences( fences ); std::vector< vk::SubmitInfo > submit_infos { m_submit_info }; - Device::getInstance().graphicsQueue().submit( m_submit_info, in_flight_fence[ m_current_frame_index ] ); + Device::getInstance().graphicsQueue().submit( m_submit_info, m_in_flight_fence[ m_current_frame_index ] ); vk::PresentInfoKHR presentInfo = {}; @@ -166,7 +177,59 @@ namespace fgl::engine return vk::Result::eSuccess; } - vk::raii::SwapchainKHR SwapChain::createSwapChain() + void PresentSwapChain:: + transitionImages( const vk::raii::CommandBuffer& command_buffer, StageID stage_id, FrameIndex frame_index ) + { + switch ( stage_id ) + { + default: + throw std::runtime_error( "Invalid StageID" ); + case INITAL: + { + const std::vector< vk::ImageMemoryBarrier > barriers { + m_render_attachments.m_color.getImage( frame_index ) + .transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ), + m_render_attachments.m_depth.getImage( frame_index ) + .transitionTo( + vk::ImageLayout::eUndefined, + vk::ImageLayout::eDepthStencilAttachmentOptimal, + vk::ImageAspectFlagBits::eDepth ) + }; + + command_buffer.pipelineBarrier( + vk::PipelineStageFlagBits::eTopOfPipe, + vk::PipelineStageFlagBits::eColorAttachmentOutput + | vk::PipelineStageFlagBits::eEarlyFragmentTests + | vk::PipelineStageFlagBits::eLateFragmentTests, + vk::DependencyFlags( 0 ), + {}, + {}, + barriers ); + + return; + } + case FINAL: + { + const std::vector< vk::ImageMemoryBarrier > barriers { + m_render_attachments.m_color.getImage( frame_index ) + .transitionColorTo( + vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::ePresentSrcKHR ), + }; + + command_buffer.pipelineBarrier( + vk::PipelineStageFlagBits::eColorAttachmentOutput, + vk::PipelineStageFlagBits::eBottomOfPipe, + vk::DependencyFlags( 0 ), + {}, + {}, + barriers ); + + return; + } + } + } + + vk::raii::SwapchainKHR PresentSwapChain::createSwapChain() { ZoneScoped; @@ -213,125 +276,41 @@ namespace fgl::engine createInfo.presentMode = m_present_mode; createInfo.clipped = VK_TRUE; - createInfo.oldSwapchain = old_swap_chain == nullptr ? VK_NULL_HANDLE : *old_swap_chain->m_swapchain; + createInfo.oldSwapchain = m_old_swap_chain == nullptr ? VK_NULL_HANDLE : *m_old_swap_chain->m_swapchain; return Device::getInstance()->createSwapchainKHR( createInfo ); } - std::vector< Image > SwapChain::createSwapchainImages() + std::vector< std::shared_ptr< Image > > PresentSwapChain::createSwapchainImages() { std::vector< vk::Image > swap_chain_images { m_swapchain.getImages() }; - std::vector< Image > images {}; + std::vector< std::shared_ptr< Image > > images {}; + images.reserve( swap_chain_images.size() ); for ( std::uint64_t i = 0; i < swap_chain_images.size(); i++ ) { auto& itter = images.emplace_back( - m_swapchain_extent, - m_surface_format.format, - swap_chain_images[ i ], - vk::ImageUsageFlagBits::eColorAttachment ); - itter.setName( "Swapchain image: " + std::to_string( i ) ); + std::make_shared< Image >( + m_swapchain_extent, + m_surface_format.format, + swap_chain_images[ i ], + vk::ImageUsageFlagBits::eColorAttachment ) ); + + itter->setName( "Swapchain image: " + std::to_string( i ) ); } return images; } - vk::raii::RenderPass SwapChain::createRenderPass() + void PresentSwapChain::createSyncObjects() { ZoneScoped; - //Present attachment + m_image_available_sem.reserve( imageCount() ); + m_render_finished_sem.reserve( imageCount() ); + m_in_flight_fence.reserve( imageCount() ); + m_images_in_flight.resize( imageCount(), VK_NULL_HANDLE ); - rendering::RenderPassBuilder builder; - - constexpr std::size_t ColorIndex { 0 }; - constexpr std::size_t DepthIndex { 1 }; - // constexpr std::size_t InputColorIndex { 2 }; - - // builder.setAttachmentCount( 3 ); - builder.setAttachmentCount( 2 ); - - auto color { builder.attachment( ColorIndex ) }; - - color.setFormat( SwapChain::getSwapChainImageFormat() ); - color.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR ); - color.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); - - auto depth { builder.attachment( DepthIndex ) }; - - depth.setFormat( pickDepthFormat() ); - depth.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilAttachmentOptimal ); - depth.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare ); - - // auto color_input { builder.attachment( InputColorIndex ) }; - // color_input.setFormat( vk::Format::eR8G8B8A8Unorm ); - // color_input.setLayouts( vk::ImageLayout::eShaderReadOnlyOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ); - // color_input.setOps( vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eDontCare ); - - auto& gui_subpass { builder.createSubpass( 0 ) }; - - // gui_subpass.addInputLayout( InputColorIndex, vk::ImageLayout::eShaderReadOnlyOptimal ); - gui_subpass.setDepthLayout( DepthIndex, vk::ImageLayout::eDepthStencilAttachmentOptimal ); - gui_subpass.addRenderLayout( ColorIndex, vk::ImageLayout::eColorAttachmentOptimal ); - - gui_subpass.addDependencyFromExternal( - vk::AccessFlagBits::eDepthStencilAttachmentWrite, - vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests ); - - gui_subpass.addDependencyFromExternal( - vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput ); - - return builder.create(); - } - - std::vector< vk::raii::Framebuffer > SwapChain::createFramebuffers() - { - ZoneScoped; - - render_attachments.color.linkImages( m_swap_chain_images ); - - render_attachments.depth.createResources( imageCount(), getSwapChainExtent() ); - render_attachments.depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) ); - - // render_attachments.input_color - // .createResources( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eTransferDst ); - - std::vector< vk::raii::Framebuffer > framebuffers {}; - - framebuffers.reserve( imageCount() ); - - for ( uint8_t i = 0; i < imageCount(); i++ ) - { - std::vector< vk::ImageView > attachments { getViewsForFrame( - // i, render_attachments.color, render_attachments.depth, render_attachments.input_color ) }; - i, - render_attachments.color, - render_attachments.depth ) }; - - //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.push_back( Device::getInstance()->createFramebuffer( framebufferInfo ) ); - } - - return framebuffers; - } - - void SwapChain::createSyncObjects() - { - ZoneScoped; - 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 {}; + constexpr vk::SemaphoreCreateInfo semaphoreInfo {}; vk::FenceCreateInfo fenceInfo {}; fenceInfo.flags = vk::FenceCreateFlagBits::eSignaled; @@ -340,13 +319,13 @@ namespace fgl::engine { auto& device { Device::getInstance() }; - image_available_sem.push_back( device->createSemaphore( semaphoreInfo ) ); - render_finished_sem.push_back( device->createSemaphore( semaphoreInfo ) ); - in_flight_fence.push_back( device->createFence( fenceInfo ) ); + m_image_available_sem.push_back( device->createSemaphore( semaphoreInfo ) ); + m_render_finished_sem.push_back( device->createSemaphore( semaphoreInfo ) ); + m_in_flight_fence.push_back( device->createFence( fenceInfo ) ); } } - vk::SurfaceFormatKHR SwapChain:: + vk::SurfaceFormatKHR PresentSwapChain:: chooseSwapSurfaceFormat( const std::vector< vk::SurfaceFormatKHR >& available_formats ) { ZoneScoped; @@ -361,7 +340,7 @@ namespace fgl::engine return available_formats[ 0 ]; } - vk::PresentModeKHR SwapChain::chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >& present_modes ) + vk::PresentModeKHR PresentSwapChain::chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >& present_modes ) { ZoneScoped; for ( const auto& mode : present_modes ) @@ -402,7 +381,7 @@ namespace fgl::engine return vk::PresentModeKHR::eFifo; } - vk::Extent2D SwapChain::chooseSwapExtent( const vk::SurfaceCapabilitiesKHR& capabilities ) const + vk::Extent2D PresentSwapChain::chooseSwapExtent( const vk::SurfaceCapabilitiesKHR& capabilities ) const { ZoneScoped; if ( capabilities.currentExtent.width != std::numeric_limits< uint32_t >::max() ) @@ -424,7 +403,7 @@ namespace fgl::engine } } - SwapChain::~SwapChain() + PresentSwapChain::~PresentSwapChain() {} /* @@ -440,18 +419,35 @@ namespace fgl::engine // return *render_attachments.input_color.m_attachment_resources.m_images[ present_index ]; // } - vk::raii::Framebuffer& SwapChain::getFrameBuffer( const PresentIndex present_index ) + vk::RenderingInfo PresentSwapChain::getRenderingInfo( const FrameIndex frame_index ) { - return m_swap_chain_buffers[ static_cast< std::size_t >( present_index ) ]; + static thread_local std::vector< vk::RenderingAttachmentInfo > color_info {}; + static thread_local vk::RenderingAttachmentInfo depth_info {}; + + color_info = { + m_render_attachments.m_color.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ) + }; + depth_info = m_render_attachments.m_depth.renderInfo( frame_index, vk::ImageLayout::eDepthAttachmentOptimal ); + + vk::RenderingInfo info {}; + + info.setColorAttachments( color_info ); + info.setPDepthAttachment( &depth_info ); + + info.layerCount = 1; + + info.setRenderArea( { { 0, 0 }, m_swapchain_extent } ); + + return info; } - bool SwapChain::compareSwapFormats( const SwapChain& other ) const + bool PresentSwapChain::compareSwapFormats( const PresentSwapChain& other ) const { return m_swap_chain_depth_format == other.m_swap_chain_depth_format && m_swap_chain_format == other.m_swap_chain_format; } - float SwapChain::extentAspectRatio() const + float PresentSwapChain::extentAspectRatio() const { return static_cast< float >( m_swapchain_extent.width ) / static_cast< float >( m_swapchain_extent.height ); } diff --git a/src/engine/rendering/PresentSwapChain.hpp b/src/engine/rendering/PresentSwapChain.hpp new file mode 100644 index 0000000..727978c --- /dev/null +++ b/src/engine/rendering/PresentSwapChain.hpp @@ -0,0 +1,114 @@ +#pragma once + +#include +#include + +#include "devices/Device.hpp" +#include "engine/FrameInfo.hpp" +#include "engine/assets/texture/Texture.hpp" +#include "pipelines/Attachment.hpp" +#include "types.hpp" + +namespace fgl::engine +{ + class PresentSwapChain + { + public: + + static constexpr FrameIndex MAX_FRAMES_IN_FLIGHT { 2 }; + + enum StageID + { + INITAL, + FINAL + }; + + private: + + PhysicalDevice& m_phy_device; + + 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; + + std::shared_ptr< PresentSwapChain > m_old_swap_chain; + + vk::raii::SwapchainKHR m_swapchain; + std::vector< std::shared_ptr< Image > > m_swap_chain_images; + + struct + { + ColoredPresentAttachment< 0 > m_color; + DepthAttachment< 1 > m_depth; + } m_render_attachments { m_swap_chain_format, m_swap_chain_depth_format }; + + std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_input_descriptors {}; + + std::vector< vk::ClearValue > m_clear_values; + + std::vector< vk::raii::Semaphore > m_image_available_sem {}; + std::vector< vk::raii::Semaphore > m_render_finished_sem {}; + std::vector< vk::raii::Fence > m_in_flight_fence {}; + std::vector< vk::Fence > m_images_in_flight {}; + + FrameIndex m_current_frame_index { 0 }; + + void init(); + [[nodiscard]] vk::raii::SwapchainKHR createSwapChain(); + [[nodiscard]] std::vector< std::shared_ptr< Image > > createSwapchainImages(); + [[nodiscard]] std::vector< std::unique_ptr< descriptors::DescriptorSet > > createInputDescriptors(); + void createSyncObjects(); + + // Helper functions + [[nodiscard]] static vk::SurfaceFormatKHR + chooseSwapSurfaceFormat( const std::vector< vk::SurfaceFormatKHR >& available_formats ); + [[nodiscard]] static vk::PresentModeKHR + chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >& present_modes ); + [[nodiscard]] vk::Extent2D chooseSwapExtent( const vk::SurfaceCapabilitiesKHR& capabilities ) const; + + public: + + PresentSwapChain( vk::Extent2D windowExtent, PhysicalDevice& phy_dev ); + PresentSwapChain( vk::Extent2D windowExtent, std::shared_ptr< PresentSwapChain > previous ); + + PresentSwapChain( const PresentSwapChain& ) = delete; + PresentSwapChain& operator=( const PresentSwapChain& ) = delete; + + ~PresentSwapChain(); + + [[nodiscard]] vk::RenderingInfo getRenderingInfo( const FrameIndex frame_index ); + + // Image& getInputImage( PresentIndex present_index ) const; + + [[nodiscard]] const std::vector< vk::ClearValue >& getClearValues() const { return m_clear_values; } + + [[nodiscard]] PresentIndex imageCount() const + { + return static_cast< std::uint16_t >( m_swap_chain_images.size() ); + } + + [[nodiscard]] vk::Extent2D getSwapChainExtent() const { return m_swapchain_extent; } + + [[nodiscard]] uint32_t width() const { return m_swapchain_extent.width; } + + [[nodiscard]] uint32_t height() const { return m_swapchain_extent.height; } + + [[nodiscard]] bool compareSwapFormats( const PresentSwapChain& other ) const; + + [[nodiscard]] float extentAspectRatio() const; + + [[nodiscard]] std::pair< vk::Result, PresentIndex > acquireNextImage(); + [[nodiscard]] vk::Result + submitCommandBuffers( const vk::raii::CommandBuffer& buffers, PresentIndex present_index ); + + void transitionImages( const vk::raii::CommandBuffer& command_buffer, StageID inital, FrameIndex frame_index ); + }; + + template < typename T > + using PerFrameArray = std::array< T, PresentSwapChain::MAX_FRAMES_IN_FLIGHT >; + +} // namespace fgl::engine diff --git a/src/engine/rendering/QueuePool.cpp b/src/engine/rendering/QueuePool.cpp index 7c1127e..3e237a5 100644 --- a/src/engine/rendering/QueuePool.cpp +++ b/src/engine/rendering/QueuePool.cpp @@ -4,6 +4,7 @@ #include "QueuePool.hpp" +#include "Surface.hpp" #include "pipelines/Attachment.hpp" namespace fgl::engine diff --git a/src/engine/rendering/Renderer.cpp b/src/engine/rendering/Renderer.cpp index 2ab1d6b..3165e79 100644 --- a/src/engine/rendering/Renderer.cpp +++ b/src/engine/rendering/Renderer.cpp @@ -11,12 +11,14 @@ #include #include -#include "SwapChain.hpp" +#include "PresentSwapChain.hpp" #include "engine/Window.hpp" //clang-format: off #include +#include "RenderingFormats.hpp" + //clang-format: on namespace fgl::engine @@ -69,7 +71,7 @@ namespace fgl::engine Renderer::Renderer( Window& window, PhysicalDevice& phy_device ) : m_window( window ), m_phy_device( phy_device ), - m_swapchain( std::make_unique< SwapChain >( m_window.getExtent(), m_phy_device ) ) + m_swapchain( std::make_unique< PresentSwapChain >( m_window.getExtent(), m_phy_device ) ) { recreateSwapchain(); createCommandBuffers(); @@ -120,7 +122,7 @@ namespace fgl::engine alloc_info.pNext = VK_NULL_HANDLE; alloc_info.commandPool = Device::getInstance().getCommandPool(); alloc_info.level = vk::CommandBufferLevel::ePrimary; - alloc_info.commandBufferCount = SwapChain::MAX_FRAMES_IN_FLIGHT; + alloc_info.commandBufferCount = PresentSwapChain::MAX_FRAMES_IN_FLIGHT; m_command_buffer = Device::getInstance().device().allocateCommandBuffers( alloc_info ); @@ -156,11 +158,11 @@ namespace fgl::engine Device::getInstance().device().waitIdle(); if ( m_swapchain == nullptr ) - m_swapchain = std::make_unique< SwapChain >( extent, m_phy_device ); + m_swapchain = std::make_unique< PresentSwapChain >( extent, m_phy_device ); else { - std::shared_ptr< SwapChain > old_swap_chain { std::move( m_swapchain ) }; - m_swapchain = std::make_unique< SwapChain >( extent, old_swap_chain ); + std::shared_ptr< PresentSwapChain > old_swap_chain { std::move( m_swapchain ) }; + m_swapchain = std::make_unique< PresentSwapChain >( extent, old_swap_chain ); if ( !old_swap_chain->compareSwapFormats( *m_swapchain.get() ) ) throw std::runtime_error( "Swap chain image(or depth) format has changed!" ); @@ -215,7 +217,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_idx = + static_cast< std::uint16_t >( ( current_frame_idx + 1 ) % PresentSwapChain::MAX_FRAMES_IN_FLIGHT ); } void Renderer::setViewport( const vk::raii::CommandBuffer& buffer ) @@ -246,15 +249,11 @@ namespace fgl::engine { assert( is_frame_started && "Cannot call beginSwapChainRenderPass if frame is not in progress" ); - 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_present_index ); - render_pass_info.renderArea = { .offset = { 0, 0 }, .extent = m_swapchain->getSwapChainExtent() }; + vk::RenderingInfo info { m_swapchain->getRenderingInfo( current_present_index ) }; - render_pass_info.setClearValues( m_swapchain->getClearValues() ); + m_swapchain->transitionImages( buffer, PresentSwapChain::INITAL, current_present_index ); - buffer.beginRenderPass( render_pass_info, vk::SubpassContents::eInline ); + buffer.beginRendering( info ); setViewport( buffer ); setScissor( buffer ); @@ -264,6 +263,8 @@ namespace fgl::engine { assert( is_frame_started && "Cannot call endSwapChainRenderPass if frame is not in progress" ); - buffer.endRenderPass(); + buffer.endRendering(); + + m_swapchain->transitionImages( buffer, PresentSwapChain::FINAL, current_present_index ); } } // namespace fgl::engine diff --git a/src/engine/rendering/Renderer.hpp b/src/engine/rendering/Renderer.hpp index 9690b96..7cf6d9b 100644 --- a/src/engine/rendering/Renderer.hpp +++ b/src/engine/rendering/Renderer.hpp @@ -9,7 +9,7 @@ #include #include -#include "SwapChain.hpp" +#include "PresentSwapChain.hpp" //clang-format: off #include @@ -23,7 +23,7 @@ namespace fgl::engine { Window& m_window; PhysicalDevice& m_phy_device; - std::unique_ptr< SwapChain > m_swapchain; + std::unique_ptr< PresentSwapChain > m_swapchain; std::vector< vk::raii::CommandBuffer > m_command_buffer {}; std::vector< vk::raii::CommandBuffer > m_gui_command_buffer {}; @@ -63,8 +63,6 @@ namespace fgl::engine TracyVkCtx getCurrentTracyCTX() const { return m_tracy_ctx; } - vk::raii::RenderPass& getSwapChainRenderPass() const { return m_swapchain->getRenderPass(); } - float getAspectRatio() const { return m_swapchain->extentAspectRatio(); } vk::raii::CommandBuffer& beginFrame(); @@ -76,7 +74,7 @@ namespace fgl::engine void beginSwapchainRendererPass( vk::raii::CommandBuffer& buffer ); void endSwapchainRendererPass( vk::raii::CommandBuffer& buffer ); - SwapChain& getSwapChain() { return *m_swapchain; } + PresentSwapChain& getSwapChain() { return *m_swapchain; } // void clearInputImage( vk::raii::CommandBuffer& command_buffer ); diff --git a/src/engine/rendering/RenderingFormats.cpp b/src/engine/rendering/RenderingFormats.cpp index 8c8d245..9d08636 100644 --- a/src/engine/rendering/RenderingFormats.cpp +++ b/src/engine/rendering/RenderingFormats.cpp @@ -4,6 +4,7 @@ #include "RenderingFormats.hpp" +#include "PresentSwapChain.hpp" #include "devices/Device.hpp" namespace fgl::engine @@ -67,4 +68,22 @@ namespace fgl::engine .findSupportedFormat( formats, vk::ImageTiling::eOptimal, vk::FormatFeatureFlagBits::eSampledImage ); } + vk::Format pickPresentFormat() + { + ZoneScoped; + + const auto swapchain_details { Device::getInstance().getSwapChainSupport() }; + const auto& available_formats { swapchain_details.formats }; + + for ( const auto& format : available_formats ) + { + if ( format.format == vk::Format::eB8G8R8A8Srgb && format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear ) + { + return format.format; + } + } + + throw std::runtime_error( "failed to find a present format" ); + } + } // namespace fgl::engine diff --git a/src/engine/rendering/RenderingFormats.hpp b/src/engine/rendering/RenderingFormats.hpp index 305e15e..f219f2f 100644 --- a/src/engine/rendering/RenderingFormats.hpp +++ b/src/engine/rendering/RenderingFormats.hpp @@ -14,5 +14,6 @@ namespace fgl::engine vk::Format pickMetallicFormat(); vk::Format pickEmissiveFormat(); vk::Format pickCompositeFormat(); + vk::Format pickPresentFormat(); } // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/rendering/SwapChain.hpp b/src/engine/rendering/SwapChain.hpp deleted file mode 100644 index 7e9c549..0000000 --- a/src/engine/rendering/SwapChain.hpp +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -#include -#include - -#include "devices/Device.hpp" -#include "engine/FrameInfo.hpp" -#include "engine/assets/texture/Texture.hpp" -#include "pipelines/Attachment.hpp" -#include "types.hpp" - -namespace fgl::engine -{ - class SwapChain - { - public: - - static constexpr FrameIndex MAX_FRAMES_IN_FLIGHT { 2 }; - - private: - - PhysicalDevice& m_phy_device; - - 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; - - std::shared_ptr< SwapChain > old_swap_chain; - - vk::raii::SwapchainKHR m_swapchain; - std::vector< Image > m_swap_chain_images; - - struct - { - ColoredPresentAttachment< 0 > color; - DepthAttachment< 1 > depth; - // InputColorAttachment< 2 > input_color { vk::Format::eR8G8B8A8Unorm }; - } render_attachments; - - vk::raii::RenderPass m_render_pass; - - std::vector< vk::raii::Framebuffer > m_swap_chain_buffers; - - std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_input_descriptors {}; - - std::vector< vk::ClearValue > m_clear_values; - - 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 m_current_frame_index { 0 }; - - void init(); - [[nodiscard]] vk::raii::SwapchainKHR createSwapChain(); - [[nodiscard]] std::vector< Image > createSwapchainImages(); - [[nodiscard]] vk::raii::RenderPass createRenderPass(); - [[nodiscard]] std::vector< vk::raii::Framebuffer > createFramebuffers(); - [[nodiscard]] std::vector< std::unique_ptr< descriptors::DescriptorSet > > createInputDescriptors(); - void createSyncObjects(); - - // 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; - - public: - - SwapChain( vk::Extent2D windowExtent, PhysicalDevice& phy_dev ); - SwapChain( vk::Extent2D windowExtent, std::shared_ptr< SwapChain > previous ); - - SwapChain( const SwapChain& ) = delete; - SwapChain& operator=( const SwapChain& ) = delete; - - ~SwapChain(); - - descriptors::DescriptorSet& getInputDescriptor( const PresentIndex present_index ); - - // Image& getInputImage( PresentIndex present_index ) const; - - const std::vector< vk::ClearValue >& getClearValues() const { return m_clear_values; } - - vk::raii::Framebuffer& getFrameBuffer( PresentIndex present_index ); - - vk::raii::RenderPass& getRenderPass() { return m_render_pass; } - - PresentIndex imageCount() const { return static_cast< std::uint16_t >( m_swap_chain_images.size() ); } - - vk::Format getSwapChainImageFormat() const { return m_swap_chain_format; } - - vk::Extent2D getSwapChainExtent() const { return m_swapchain_extent; } - - uint32_t width() const { return m_swapchain_extent.width; } - - uint32_t height() const { return m_swapchain_extent.height; } - - bool compareSwapFormats( const SwapChain& other ) const; - - float extentAspectRatio() const; - - [[nodiscard]] std::pair< vk::Result, PresentIndex > acquireNextImage(); - [[nodiscard]] vk::Result - submitCommandBuffers( const vk::raii::CommandBuffer& buffers, PresentIndex present_index ); - }; - - template < typename T > - using PerFrameArray = std::array< T, SwapChain::MAX_FRAMES_IN_FLIGHT >; - -} // namespace fgl::engine diff --git a/src/engine/rendering/pipelines/Attachment.hpp b/src/engine/rendering/pipelines/Attachment.hpp index 5c7d04d..b864127 100644 --- a/src/engine/rendering/pipelines/Attachment.hpp +++ b/src/engine/rendering/pipelines/Attachment.hpp @@ -33,15 +33,15 @@ namespace fgl::engine vk::ImageUsageFlags usage > class Attachment { - vk::AttachmentDescription description {}; + vk::AttachmentDescription m_description {}; public: vk::ClearValue m_clear_value {}; - void setClear( vk::ClearColorValue value ) { m_clear_value = value; } + void setClear( const vk::ClearColorValue value ) { m_clear_value = value; } - void setClear( vk::ClearDepthStencilValue value ) { m_clear_value = value; } + void setClear( const vk::ClearDepthStencilValue value ) { m_clear_value = value; } void setName( const char* str ) { @@ -62,26 +62,37 @@ namespace fgl::engine constexpr Attachment( const vk::Format format ) { assert( format != vk::Format::eUndefined && "Attachment format must not be undefined" ); - description.format = format; - description.samples = vk::SampleCountFlagBits::e1; - description.loadOp = load_op; - description.storeOp = store_op; - description.stencilLoadOp = vk::AttachmentLoadOp::eDontCare; - description.stencilStoreOp = vk::AttachmentStoreOp::eDontCare; - description.initialLayout = inital_layout; - description.finalLayout = final_layout; + m_description.format = format; + m_description.samples = vk::SampleCountFlagBits::e1; + m_description.loadOp = load_op; + m_description.storeOp = store_op; + m_description.stencilLoadOp = vk::AttachmentLoadOp::eDontCare; + m_description.stencilStoreOp = vk::AttachmentStoreOp::eDontCare; + m_description.initialLayout = inital_layout; + m_description.finalLayout = final_layout; } - void attachImageView( std::uint16_t frame_idx, std::shared_ptr< ImageView > image_view ) + void attachImageView( const std::uint16_t frame_idx, std::shared_ptr< ImageView > image_view ) { 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 linkImage( std::uint16_t frame_idx, Image& image ) { attachImageView( frame_idx, image.getView() ); } + void attachImage( const std::uint16_t frame_index, const std::shared_ptr< Image >& image ) + { + auto& images { m_attachment_resources.m_images }; + if ( images.size() <= frame_index ) images.resize( frame_index + 1 ); + images[ frame_index ] = std::move( image ); + } - void linkImages( std::vector< Image >& images ) + void linkImage( const std::uint16_t frame_idx, const std::shared_ptr< Image >& image ) + { + attachImage( frame_idx, image ); + attachImageView( frame_idx, image->getView() ); + } + + void linkImages( const std::vector< std::shared_ptr< Image > >& images ) { assert( images.size() > 0 ); for ( std::uint16_t i = 0; i < images.size(); ++i ) @@ -91,7 +102,9 @@ namespace fgl::engine } void createResources( - const std::uint32_t count, vk::Extent2D extent, vk::ImageUsageFlags extra_flags = vk::ImageUsageFlags( 0 ) ) + const std::uint32_t count, + const vk::Extent2D extent, + const vk::ImageUsageFlags extra_flags = vk::ImageUsageFlags( 0 ) ) { for ( std::uint16_t i = 0; i < count; ++i ) { @@ -100,7 +113,7 @@ namespace fgl::engine const auto& itter { images.emplace_back( std::make_shared< Image >( extent, - description.format, + m_description.format, usage | vk::ImageUsageFlagBits::eInputAttachment | extra_flags, vk::ImageLayout::eUndefined, final_layout ) ) }; @@ -114,7 +127,7 @@ namespace fgl::engine { auto image { std::make_shared< Image >( extent, - description.format, + m_description.format, usage | vk::ImageUsageFlagBits::eInputAttachment | extra_flags, vk::ImageLayout::eUndefined, final_layout ) }; @@ -150,7 +163,7 @@ namespace fgl::engine return info; } - constexpr vk::AttachmentDescription& desc() { return description; } + constexpr vk::AttachmentDescription& desc() { return m_description; } friend class RenderPassBuilder; }; diff --git a/src/engine/rendering/pipelines/Shader.cpp b/src/engine/rendering/pipelines/Shader.cpp index 99a9c73..5730a1d 100644 --- a/src/engine/rendering/pipelines/Shader.cpp +++ b/src/engine/rendering/pipelines/Shader.cpp @@ -29,7 +29,8 @@ namespace fgl::engine } else { - log::critical( "Failed to load shader module {}. Path not found", path.string() ); + log::critical( + "Failed to load shader module {}. Path not found", std::filesystem::absolute( path ).string() ); throw std::runtime_error( "Failed to load shader module. Path not found" ); } } diff --git a/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp b/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp index 3f63d30..4fbd3e5 100644 --- a/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp +++ b/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp @@ -7,8 +7,8 @@ #include "AttachmentBuilder.hpp" #include "Pipeline.hpp" #include "engine/descriptors/DescriptorSetLayout.hpp" +#include "engine/rendering/PresentSwapChain.hpp" #include "engine/rendering/RenderingFormats.hpp" -#include "engine/rendering/SwapChain.hpp" namespace fgl::engine { diff --git a/src/engine/systems/composition/GuiSystem.cpp b/src/engine/systems/composition/GuiSystem.cpp index c754aeb..9a318bd 100644 --- a/src/engine/systems/composition/GuiSystem.cpp +++ b/src/engine/systems/composition/GuiSystem.cpp @@ -9,11 +9,12 @@ #include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp" #include "engine/rendering/pipelines/v2/Pipeline.hpp" #include "engine/rendering/pipelines/v2/PipelineBuilder.hpp" +#include "rendering/RenderingFormats.hpp" namespace fgl::engine { - GuiSystem::GuiSystem( vk::raii::RenderPass& render_pass ) + GuiSystem::GuiSystem() { //descriptors::DescriptorSetCollection descriptors { gui_descriptor_set }; @@ -27,7 +28,7 @@ namespace fgl::engine builder.setVertexShader( Shader::loadVertex( "shaders/fullscreen.vert" ) ); builder.setFragmentShader( Shader::loadFragment( "shaders/gui-compose.frag" ) ); - builder.addColorAttachment().setFormat( vk::Format::eR8G8B8A8Unorm ).finish(); + builder.addColorAttachment().setFormat( pickPresentFormat() ).finish(); m_pipeline = builder.create(); m_pipeline->setDebugName( "Gui Pipeline" ); diff --git a/src/engine/systems/composition/GuiSystem.hpp b/src/engine/systems/composition/GuiSystem.hpp index 0387aaf..2a32f80 100644 --- a/src/engine/systems/composition/GuiSystem.hpp +++ b/src/engine/systems/composition/GuiSystem.hpp @@ -24,9 +24,10 @@ namespace fgl::engine public: - GuiSystem( vk::raii::RenderPass& render_pass ); + GuiSystem(); - FGL_DELETE_ALL_RO5( GuiSystem ); + FGL_DELETE_MOVE( GuiSystem ); + FGL_DELETE_COPY( GuiSystem ); void pass( FrameInfo& info ); }; diff --git a/src/engine/systems/render/EntityRendererSystem.hpp b/src/engine/systems/render/EntityRendererSystem.hpp index 5811f5d..7eb66c0 100644 --- a/src/engine/systems/render/EntityRendererSystem.hpp +++ b/src/engine/systems/render/EntityRendererSystem.hpp @@ -8,7 +8,7 @@ #include "engine/assets/model/Model.hpp" #include "engine/memory/buffers/vector/HostVector.hpp" -#include "engine/rendering/SwapChain.hpp" +#include "engine/rendering/PresentSwapChain.hpp" namespace fgl::engine { diff --git a/src/engine/systems/render/LineDrawer.hpp b/src/engine/systems/render/LineDrawer.hpp index de5bad0..7c62c12 100644 --- a/src/engine/systems/render/LineDrawer.hpp +++ b/src/engine/systems/render/LineDrawer.hpp @@ -5,7 +5,7 @@ #pragma once #include "engine/descriptors/Descriptor.hpp" #include "engine/memory/buffers/vector/HostVector.hpp" -#include "engine/rendering/SwapChain.hpp" +#include "engine/rendering/PresentSwapChain.hpp" namespace fgl::engine {