diff --git a/src/editor/src/gui/preview.cpp b/src/editor/src/gui/preview.cpp index bb7e198..5fc7c13 100644 --- a/src/editor/src/gui/preview.cpp +++ b/src/editor/src/gui/preview.cpp @@ -8,7 +8,7 @@ #include "engine/assets/model/Model.hpp" #include "engine/assets/model/builders/SceneBuilder.hpp" #include "engine/camera/Camera.hpp" -#include "engine/camera/CameraSwapchain.hpp" +#include "engine/camera/GBufferSwapchain.hpp" #include "engine/filesystem/scanner/FileScanner.hpp" #include "engine/filesystem/types.hpp" #include "engine/gameobjects/components/ModelComponent.hpp" @@ -53,9 +53,7 @@ namespace fgl::engine::gui obj.addFlag( IsEntity | IsVisible ); - auto component { - std::make_unique< ModelComponent >( std::move( model ) ) - }; + auto component { std::make_unique< ModelComponent >( std::move( model ) ) }; obj.addComponent( std::move( component ) ); @@ -208,16 +206,17 @@ namespace fgl::engine::gui default: [[fallthrough]]; case Composite: - camera.getSwapchain().m_g_buffer_composite_img[ frame_index ]->drawImGui( target_size ); + camera.getCompositeSwapchain().m_gbuffer_target[ frame_index ]->drawImGui( target_size ); + // camera.getSwapchain().m_g_buffer_composite_img[ frame_index ]->drawImGui( target_size ); break; case Albedo: - camera.getSwapchain().m_g_buffer_color_img[ frame_index ]->drawImGui( target_size ); + // camera.getSwapchain().m_g_buffer_color_img[ frame_index ]->drawImGui( target_size ); break; case Normal: - camera.getSwapchain().m_g_buffer_normal_img[ frame_index ]->drawImGui( target_size ); + // camera.getSwapchain().m_g_buffer_normal_img[ frame_index ]->drawImGui( target_size ); break; case Position: - camera.getSwapchain().m_g_buffer_position_img[ frame_index ]->drawImGui( target_size ); + // camera.getSwapchain().m_g_buffer_position_img[ frame_index ]->drawImGui( target_size ); break; } diff --git a/src/editor/src/main.cpp b/src/editor/src/main.cpp index 5254e54..f74722f 100644 --- a/src/editor/src/main.cpp +++ b/src/editor/src/main.cpp @@ -35,46 +35,53 @@ int main() log::debug( "Vulkan instance version: {}.{}.{}.{}", major, minor, patch, minor ); - EngineContext engine_ctx {}; - - // We start by hooking into the imgui rendering. - engine_ctx.hookInitImGui( gui::initGui ); - engine_ctx.hookPreFrame( gui::startDrawImGui ); - engine_ctx.hookEarlyFrame( gui::drawImGui ); - engine_ctx.hookLateFrame( gui::endDrawImGui ); - engine_ctx.hookDestruction( gui::cleanupImGui ); - - // Now we need to create the camera for the editor. - CameraManager& camera_manager { engine_ctx.cameraManager() }; - - auto& editor_camera { camera_manager.getPrimary() }; - - editor_camera->setFOV( glm::radians( 90.0f ) ); - - //! Will be true until the window says it wants to close. - while ( engine_ctx.good() ) + try { - debug::timing::reset(); - engine_ctx.tickDeltaTime(); + EngineContext engine_ctx {}; - engine_ctx.handleTransfers(); + // We start by hooking into the imgui rendering. + engine_ctx.hookInitImGui( gui::initGui ); + engine_ctx.hookPreFrame( gui::startDrawImGui ); + engine_ctx.hookEarlyFrame( gui::drawImGui ); + engine_ctx.hookLateFrame( gui::endDrawImGui ); + engine_ctx.hookDestruction( gui::cleanupImGui ); - // Process input - engine_ctx.processInput(); + // Now we need to create the camera for the editor. + CameraManager& camera_manager { engine_ctx.cameraManager() }; - // Here we can decide if we want to tick fully or not. + auto& editor_camera { camera_manager.getPrimary() }; - // Simulate step - engine_ctx.tickSimulation(); + editor_camera->setFOV( glm::radians( 90.0f ) ); - // Update the viewer camera + //! Will be true until the window says it wants to close. + while ( engine_ctx.good() ) + { + debug::timing::reset(); + engine_ctx.tickDeltaTime(); - // Render step - engine_ctx.renderFrame(); + engine_ctx.handleTransfers(); - engine_ctx.finishFrame(); - // This will 'end' the root node, Which is created on 'reset' - debug::timing::internal::pop(); + // Process input + engine_ctx.processInput(); + + // Here we can decide if we want to tick fully or not. + + // Simulate step + engine_ctx.tickSimulation(); + + // Update the viewer camera + + // Render step + engine_ctx.renderFrame(); + + engine_ctx.finishFrame(); + // This will 'end' the root node, Which is created on 'reset' + debug::timing::internal::pop(); + } + } + catch ( const vk::LayerNotPresentError& e ) + { + log::info( "{}:{}", e.code().message(), e.what() ); } return EXIT_SUCCESS; diff --git a/src/engine/EngineContext.cpp b/src/engine/EngineContext.cpp index 0bc7cca..45acff8 100644 --- a/src/engine/EngineContext.cpp +++ b/src/engine/EngineContext.cpp @@ -14,7 +14,7 @@ #include "assets/material/Material.hpp" #include "camera/Camera.hpp" #include "camera/CameraManager.hpp" -#include "camera/CameraRenderer.hpp" +#include "camera/GBufferRenderer.hpp" #include "debug/timing/FlameGraph.hpp" #include "engine/assets/model/builders/SceneBuilder.hpp" #include "engine/assets/transfer/TransferManager.hpp" diff --git a/src/engine/FrameInfo.cpp b/src/engine/FrameInfo.cpp index 1e8a4e9..a154adf 100644 --- a/src/engine/FrameInfo.cpp +++ b/src/engine/FrameInfo.cpp @@ -5,7 +5,7 @@ #include "FrameInfo.hpp" #include "camera/Camera.hpp" -#include "camera/CameraSwapchain.hpp" +#include "camera/GBufferSwapchain.hpp" namespace fgl::engine { diff --git a/src/engine/FrameInfo.hpp b/src/engine/FrameInfo.hpp index a229ffa..3ed3202 100644 --- a/src/engine/FrameInfo.hpp +++ b/src/engine/FrameInfo.hpp @@ -5,6 +5,7 @@ #pragma once //clang-format: off +#include #include //clang-format: on diff --git a/src/engine/assets/image/Image.cpp b/src/engine/assets/image/Image.cpp index ef91966..6b76ce5 100644 --- a/src/engine/assets/image/Image.cpp +++ b/src/engine/assets/image/Image.cpp @@ -11,17 +11,188 @@ namespace fgl::engine std::shared_ptr< ImageView > Image::getView() { - if ( !view.expired() ) - return view.lock(); + if ( !m_view.expired() ) + return m_view.lock(); else { assert( m_handle ); auto ptr { std::make_shared< ImageView >( m_handle ) }; - view = ptr; + m_view = ptr; return ptr; } } + constexpr vk::AccessFlags getAccessFlags( const vk::ImageLayout layout ) + { + switch ( layout ) + { + case vk::ImageLayout::eUndefined: + return vk::AccessFlags( 0 ); + case vk::ImageLayout::eGeneral: + break; + case vk::ImageLayout::eColorAttachmentOptimal: + return vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite; + case vk::ImageLayout::eDepthStencilAttachmentOptimal: + break; + case vk::ImageLayout::eDepthStencilReadOnlyOptimal: + break; + case vk::ImageLayout::eShaderReadOnlyOptimal: + return vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eInputAttachmentRead; + case vk::ImageLayout::eTransferSrcOptimal: + return vk::AccessFlagBits::eTransferRead; + case vk::ImageLayout::eTransferDstOptimal: + return vk::AccessFlagBits::eTransferWrite; + case vk::ImageLayout::ePreinitialized: + return vk::AccessFlagBits::eHostWrite; + case vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal: + break; + case vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal: + break; + 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: + break; + case vk::ImageLayout::eAttachmentOptimal: + break; + case vk::ImageLayout::ePresentSrcKHR: + return vk::AccessFlags( 0 ); + case vk::ImageLayout::eVideoDecodeDstKHR: + break; + case vk::ImageLayout::eVideoDecodeSrcKHR: + break; + case vk::ImageLayout::eVideoDecodeDpbKHR: + break; + case vk::ImageLayout::eSharedPresentKHR: + break; + case vk::ImageLayout::eFragmentDensityMapOptimalEXT: + break; + case vk::ImageLayout::eFragmentShadingRateAttachmentOptimalKHR: + return vk::AccessFlagBits::eFragmentShadingRateAttachmentReadKHR; + case vk::ImageLayout::eRenderingLocalReadKHR: + return vk::AccessFlagBits::eColorAttachmentWrite; + case vk::ImageLayout::eVideoEncodeDstKHR: + break; + case vk::ImageLayout::eVideoEncodeSrcKHR: + break; + case vk::ImageLayout::eVideoEncodeDpbKHR: + break; + case vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT: + break; + default: + FGL_UNREACHABLE(); + } + + FGL_UNREACHABLE(); + } + + constexpr vk::PipelineStageFlags getPipelineStageFlags( const vk::ImageLayout layout ) + { + switch ( layout ) + { + default: + FGL_UNREACHABLE(); + case vk::ImageLayout::eUndefined: + return vk::PipelineStageFlagBits::eTopOfPipe; + case vk::ImageLayout::eGeneral: + break; + case vk::ImageLayout::eColorAttachmentOptimal: + return vk::PipelineStageFlagBits::eColorAttachmentOutput; + case vk::ImageLayout::eDepthStencilAttachmentOptimal: + break; + case vk::ImageLayout::eDepthStencilReadOnlyOptimal: + break; + case vk::ImageLayout::eShaderReadOnlyOptimal: + return vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eFragmentShader; + case vk::ImageLayout::eTransferSrcOptimal: + [[fallthrough]]; + case vk::ImageLayout::eTransferDstOptimal: + return vk::PipelineStageFlagBits::eTransfer; + case vk::ImageLayout::ePreinitialized: + break; + case vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal: + break; + case vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal: + break; + case vk::ImageLayout::eDepthAttachmentOptimal: + break; + case vk::ImageLayout::eDepthReadOnlyOptimal: + break; + case vk::ImageLayout::eStencilAttachmentOptimal: + break; + case vk::ImageLayout::eStencilReadOnlyOptimal: + break; + case vk::ImageLayout::eReadOnlyOptimal: + break; + case vk::ImageLayout::eAttachmentOptimal: + break; + case vk::ImageLayout::ePresentSrcKHR: + return vk::PipelineStageFlagBits::eBottomOfPipe; + case vk::ImageLayout::eVideoDecodeDstKHR: + break; + case vk::ImageLayout::eVideoDecodeSrcKHR: + break; + case vk::ImageLayout::eVideoDecodeDpbKHR: + break; + case vk::ImageLayout::eSharedPresentKHR: + break; + case vk::ImageLayout::eFragmentDensityMapOptimalEXT: + break; + case vk::ImageLayout::eFragmentShadingRateAttachmentOptimalKHR: + break; + case vk::ImageLayout::eRenderingLocalReadKHR: + break; + case vk::ImageLayout::eVideoEncodeDstKHR: + break; + case vk::ImageLayout::eVideoEncodeSrcKHR: + break; + case vk::ImageLayout::eVideoEncodeDpbKHR: + break; + case vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT: + break; + } + + FGL_UNREACHABLE(); + } + + vk::ImageMemoryBarrier Image::transitionTo( + const vk::ImageLayout old_layout, + const vk::ImageLayout new_layout, + const vk::ImageSubresourceRange& range ) const + { + vk::ImageMemoryBarrier barrier {}; + barrier.srcAccessMask = getAccessFlags( old_layout ); + barrier.dstAccessMask = getAccessFlags( new_layout ); + + barrier.oldLayout = old_layout; + barrier.newLayout = new_layout; + + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + + barrier.subresourceRange = range; + + barrier.setImage( this->getVkImage() ); + + return barrier; + } + + vk::ImageMemoryBarrier Image::transitionTo( + const vk::ImageLayout old_layout, const vk::ImageLayout new_layout, const vk::ImageAspectFlags aspect ) + { + const vk::ImageSubresourceRange subresource { aspect, 0, 1, 0, 1 }; + + const vk::ImageMemoryBarrier barrier { transitionTo( old_layout, new_layout, subresource ) }; + + return barrier; + } + Image::Image( const vk::Extent2D extent, const vk::Format format, @@ -44,7 +215,7 @@ namespace fgl::engine Image& Image::operator=( const Image& other ) { m_handle = other.m_handle; - view = {}; + m_view = {}; return *this; } @@ -56,7 +227,7 @@ namespace fgl::engine Image& Image::operator=( Image&& other ) noexcept { m_handle = std::move( other.m_handle ); - view = std::move( other.view ); + m_view = std::move( other.m_view ); m_extent = other.m_extent; return *this; } diff --git a/src/engine/assets/image/Image.hpp b/src/engine/assets/image/Image.hpp index cfb9a44..cffe7bf 100644 --- a/src/engine/assets/image/Image.hpp +++ b/src/engine/assets/image/Image.hpp @@ -20,7 +20,7 @@ namespace fgl::engine class Image { std::shared_ptr< ImageHandle > m_handle; - std::weak_ptr< ImageView > view {}; + std::weak_ptr< ImageView > m_view {}; vk::Extent2D m_extent; friend class memory::TransferManager; @@ -54,6 +54,16 @@ namespace fgl::engine const vk::Extent2D& getExtent() const { return m_extent; } [[nodiscard]] std::shared_ptr< ImageView > getView(); + + 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 ); + + inline vk::ImageMemoryBarrier transitionColorTo(vk::ImageLayout old_layout, vk::ImageLayout new_layout) + { + return transitionTo( old_layout, new_layout, vk::ImageAspectFlagBits::eColor ); + } }; } // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/assets/texture/Texture.cpp b/src/engine/assets/texture/Texture.cpp index 3b118e5..0187971 100644 --- a/src/engine/assets/texture/Texture.cpp +++ b/src/engine/assets/texture/Texture.cpp @@ -109,12 +109,13 @@ namespace fgl::engine Texture::Texture( std::vector< std::byte >&& data, const vk::Extent2D extent, const vk::Format format ) : m_texture_id( texture_id_pool.getID() ), - m_image( std::make_shared< Image >( - extent, - format, - vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled, - vk::ImageLayout::eUndefined, - vk::ImageLayout::eShaderReadOnlyOptimal ) ), + m_image( + std::make_shared< Image >( + extent, + format, + vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled, + vk::ImageLayout::eUndefined, + vk::ImageLayout::eShaderReadOnlyOptimal ) ), m_image_view( m_image->getView() ), m_extent( extent ), m_name( "Default Texture Name" ) @@ -147,6 +148,11 @@ namespace fgl::engine texture_id_pool.markUnused( m_texture_id ); } + Image& Texture::getImageRef() + { + return *m_image; + } + vk::DescriptorImageInfo Texture::getDescriptor() const { return m_image_view->descriptorInfo( vk::ImageLayout::eGeneral ); diff --git a/src/engine/assets/texture/Texture.hpp b/src/engine/assets/texture/Texture.hpp index c7e2943..c575524 100644 --- a/src/engine/assets/texture/Texture.hpp +++ b/src/engine/assets/texture/Texture.hpp @@ -89,6 +89,8 @@ namespace fgl::engine ~Texture(); + Image& getImageRef(); + Texture( const Texture& ) = delete; Texture& operator=( const Texture& ) = delete; diff --git a/src/engine/camera/Camera.cpp b/src/engine/camera/Camera.cpp index 1cf983c..f0e481b 100644 --- a/src/engine/camera/Camera.cpp +++ b/src/engine/camera/Camera.cpp @@ -9,8 +9,8 @@ #include #include "CameraInfo.hpp" -#include "CameraRenderer.hpp" -#include "CameraSwapchain.hpp" +#include "GBufferRenderer.hpp" +#include "GBufferSwapchain.hpp" #include "engine/debug/timing/FlameGraph.hpp" namespace fgl::engine @@ -69,11 +69,11 @@ namespace fgl::engine { ZoneScopedN( "Camera::pass" ); auto timer = debug::timing::push( "Camera" ); - if ( m_cold && m_swapchain ) + if ( m_cold && m_gbuffer_swapchain ) { //TODO: Make some way to destroy the swapchain in a deffered manner. - m_old_swapchain = m_swapchain; - m_swapchain = nullptr; + // m_old_swapchain = m_gbuffer_swapchain; + m_gbuffer_swapchain = nullptr; m_active = false; } @@ -82,19 +82,25 @@ namespace fgl::engine assert( frame_info.camera == nullptr ); frame_info.camera = this; - if ( m_swapchain->getExtent() != m_target_extent ) + if ( m_gbuffer_swapchain->getExtent() != m_target_extent ) { remakeSwapchain( m_target_extent ); } updateInfo( frame_info.frame_idx ); - m_camera_renderer->pass( frame_info, *m_swapchain ); + FGL_ASSERT( m_camera_renderer, "Camera renderer should not be nullptr" ); + m_camera_renderer->pass( frame_info, *m_gbuffer_swapchain ); frame_info.camera = nullptr; } - CameraSwapchain& Camera::getSwapchain() const + GBufferSwapchain& Camera::getSwapchain() const { - return *m_swapchain; + return *m_gbuffer_swapchain; + } + + CompositeSwapchain& Camera::getCompositeSwapchain() const + { + return *m_composite_swapchain; } void Camera::setViewport( const vk::raii::CommandBuffer& command_buffer ) @@ -103,7 +109,7 @@ namespace fgl::engine viewport.x = 0.0f; viewport.y = 0.0f; - const auto& [ width, height ] = m_swapchain->getExtent(); + const auto& [ width, height ] = m_gbuffer_swapchain->getExtent(); viewport.width = static_cast< float >( width ); viewport.height = static_cast< float >( height ); viewport.minDepth = 0.0f; @@ -116,7 +122,7 @@ namespace fgl::engine void Camera::setScissor( const vk::raii::CommandBuffer& command_buffer ) { - const vk::Rect2D scissor { { 0, 0 }, m_swapchain->getExtent() }; + const vk::Rect2D scissor { { 0, 0 }, m_gbuffer_swapchain->getExtent() }; const std::vector< vk::Rect2D > scissors { scissor }; @@ -126,8 +132,9 @@ namespace fgl::engine void Camera::remakeSwapchain( vk::Extent2D extent ) { this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE ); - m_old_swapchain = m_swapchain; - m_swapchain = std::make_shared< CameraSwapchain >( m_camera_renderer->getRenderpass(), extent ); + + m_composite_swapchain = std::make_unique< CompositeSwapchain >( extent ); + m_gbuffer_swapchain = std::make_unique< GBufferSwapchain >( extent ); } void Camera::setName( const std::string_view str ) @@ -137,15 +144,16 @@ namespace fgl::engine float Camera::aspectRatio() const { - return m_swapchain->getAspectRatio(); + return m_gbuffer_swapchain->getAspectRatio(); } void Camera:: copyOutput( const vk::raii::CommandBuffer& command_buffer, const FrameIndex frame_index, Image& target ) { - assert( m_swapchain->getExtent() == target.getExtent() ); + assert( m_gbuffer_swapchain->getExtent() == target.getExtent() ); - Image& source { this->getSwapchain().getOutput( frame_index ) }; + Texture& source_tex { *m_composite_swapchain->m_gbuffer_target[ frame_index ] }; + Image& source { source_tex.getImageRef() }; vk::ImageSubresourceRange range {}; range.aspectMask = vk::ImageAspectFlagBits::eColor; @@ -192,7 +200,7 @@ namespace fgl::engine { barrier_from_source } ); vk::ImageCopy region {}; - region.extent = vk::Extent3D( m_swapchain->getExtent(), 1 ); + region.extent = vk::Extent3D( m_gbuffer_swapchain->getExtent(), 1 ); region.srcSubresource.aspectMask = vk::ImageAspectFlagBits::eColor; region.srcSubresource.layerCount = 1; @@ -318,14 +326,14 @@ namespace fgl::engine return camera_descriptor_set; } - Camera::Camera( const vk::Extent2D extent, memory::Buffer& buffer, std::unique_ptr< CameraRenderer >& renderer ) : - m_camera_renderer( renderer ), - m_transform(), + Camera::Camera( const vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer ) : m_target_extent( extent ), - m_camera_frame_info( buffer, SwapChain::MAX_FRAMES_IN_FLIGHT ), - m_swapchain( std::make_shared< CameraSwapchain >( m_camera_renderer->getRenderpass(), m_target_extent ) ), - m_name() + 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 ) { + 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 ) ); diff --git a/src/engine/camera/Camera.hpp b/src/engine/camera/Camera.hpp index 73950c9..1314b4e 100644 --- a/src/engine/camera/Camera.hpp +++ b/src/engine/camera/Camera.hpp @@ -12,6 +12,7 @@ #include #pragma GCC diagnostic pop +#include "CompositeSwapchain.hpp" #include "engine/descriptors/DescriptorSet.hpp" #include "engine/memory/buffers/HostSingleT.hpp" #include "engine/memory/buffers/UniqueFrameSuballocation.hpp" @@ -34,10 +35,10 @@ namespace fgl::engine } class Image; struct FrameInfo; - class CameraRenderer; + class GBufferRenderer; struct CameraInfo; - class CameraSwapchain; + class GBufferSwapchain; class Camera; FrustumBase createFrustum( float aspect, float fovy, float near, float far ); @@ -48,7 +49,12 @@ namespace fgl::engine { inline static CameraIDX m_camera_counter { 0 }; - std::unique_ptr< CameraRenderer >& m_camera_renderer; + vk::Extent2D m_target_extent; + + std::unique_ptr< CompositeSwapchain > m_composite_swapchain; + std::unique_ptr< GBufferSwapchain > m_gbuffer_swapchain; + + std::shared_ptr< GBufferRenderer > m_camera_renderer; //! True if the camera is active and to be rendered bool m_active { true }; @@ -73,7 +79,6 @@ namespace fgl::engine WorldTransform m_transform; - vk::Extent2D m_target_extent; float m_fov_y { glm::radians( 90.0f ) }; PerFrameSuballocation< HostSingleT< CameraInfo > > m_camera_frame_info; @@ -81,10 +86,6 @@ namespace fgl::engine // Camera info is expected at binding 0 std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_camera_info_descriptors {}; - // TODO: Remove this old swapchain and instead do a proper deffered cleanup of it. - std::shared_ptr< CameraSwapchain > m_old_swapchain { nullptr }; - std::shared_ptr< CameraSwapchain > m_swapchain; - std::string m_name; Matrix< MatrixType::ModelToWorld > frustumTranslationMatrix() const; @@ -96,7 +97,7 @@ namespace fgl::engine Camera( vk::Extent2D test_extent ) : m_target_extent( test_extent ) {} #endif - Camera( vk::Extent2D extent, memory::Buffer& buffer, std::unique_ptr< CameraRenderer >& renderer ); + Camera( vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer ); friend class CameraManager; @@ -114,8 +115,6 @@ namespace fgl::engine const std::string& getName() const; - static void initCameraRenderer(); - void setExtent( vk::Extent2D extent ); const Rotation& getRotation() const { return m_transform.rotation; } @@ -171,7 +170,8 @@ namespace fgl::engine FGL_FORCE_INLINE NormalVector getDown() const { - return NormalVector( glm::vec3( m_inverse_view_matrix[ 1 ] ) ); } + return NormalVector( glm::vec3( m_inverse_view_matrix[ 1 ] ) ); + } //! Updates the required info for rendering void updateInfo( FrameIndex frame_index ); @@ -182,7 +182,8 @@ namespace fgl::engine //! Performs the render pass for this camera void pass( FrameInfo& frame_info ); - CameraSwapchain& getSwapchain() const; + GBufferSwapchain& getSwapchain() const; + CompositeSwapchain& getCompositeSwapchain() const; void setViewport( const vk::raii::CommandBuffer& command_buffer ); void setScissor( const vk::raii::CommandBuffer& command_buffer ); @@ -204,6 +205,4 @@ namespace fgl::engine #endif }; - descriptors::DescriptorSetLayout& getCameraDescriptorSet(); - } // namespace fgl::engine diff --git a/src/engine/camera/Camera.puml b/src/engine/camera/Camera.puml new file mode 100644 index 0000000..a3b1d32 --- /dev/null +++ b/src/engine/camera/Camera.puml @@ -0,0 +1,46 @@ +@startuml +'https://plantuml.com/component-diagram + + +package "Some Group" { + HTTP - [First Component] + [Another Component] +} + +node "Other Groups" { + FTP - [Second Component] + [First Component] --> FTP +} + +cloud { + [Example 1] +} + + +database "MySql" { + folder "This is my folder" { + [Folder 3] + } + frame "Foo" { + [Frame 4] + } +} + + +[Another Component] --> [Example 1] +[Example 1] --> [Folder 3] +[Folder 3] --> [Frame 4] + +node "GBufferSwapchain" { +node "Albedo" +node "Metallic" +node "Position & Depth 16F4" +} + + + + + + + +@enduml \ No newline at end of file diff --git a/src/engine/camera/CameraManager.cpp b/src/engine/camera/CameraManager.cpp index 21f600e..3690d8c 100644 --- a/src/engine/camera/CameraManager.cpp +++ b/src/engine/camera/CameraManager.cpp @@ -5,7 +5,7 @@ #include "CameraManager.hpp" #include "Camera.hpp" -#include "CameraRenderer.hpp" +#include "GBufferRenderer.hpp" #include "engine/debug/DEBUG_NAMES.hpp" #include "engine/math/literals/size.hpp" @@ -25,7 +25,7 @@ namespace fgl::engine } CameraManager::CameraManager() : - m_renderer( std::make_unique< CameraRenderer >() ), + m_renderer( std::make_shared< GBufferRenderer >() ), m_data_buffer( 4_KiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible ) { m_primary_camera = createCamera( { 1920, 1080 } ); diff --git a/src/engine/camera/CameraManager.hpp b/src/engine/camera/CameraManager.hpp index 63cb205..b5d16d5 100644 --- a/src/engine/camera/CameraManager.hpp +++ b/src/engine/camera/CameraManager.hpp @@ -17,7 +17,7 @@ namespace fgl::engine class CameraManager { - std::unique_ptr< CameraRenderer > m_renderer; + std::shared_ptr< GBufferRenderer > m_renderer; memory::Buffer m_data_buffer; std::shared_ptr< Camera > m_primary_camera { nullptr }; diff --git a/src/engine/camera/CameraRenderer.cpp b/src/engine/camera/CameraRenderer.cpp deleted file mode 100644 index fa9868e..0000000 --- a/src/engine/camera/CameraRenderer.cpp +++ /dev/null @@ -1,182 +0,0 @@ -// -// Created by kj16609 on 7/21/24. -// - -#include "CameraRenderer.hpp" - -#include "CameraSwapchain.hpp" -#include "engine/rendering/renderpass/RenderPass.hpp" - -namespace fgl::engine -{ - class CameraSwapchain; - - vk::raii::RenderPass CameraRenderer::createRenderPass() - { - rendering::RenderPassBuilder builder {}; - - builder.setAttachmentCount( 7 ); - - // Set formats for each item in the swapchain - - //XYZ in world space - auto position { builder.attachment( POSITION_INDEX ) }; - position.setFormat( pickPositionFormat() ); // position - position.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); - position.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); - - //RGBA - auto normal { builder.attachment( NORMAL_INDEX ) }; - normal.setFormat( pickNormalFormat() ); // normal - normal.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); - normal.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); - - // RGBA - auto color { builder.attachment( COLOR_INDEX ) }; - color.setFormat( pickColorFormat() ); // color - color.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); - color.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); - - // Metallic, Roughness, Occlusion - auto metallic_roughness { builder.attachment( METALLIC_INDEX ) }; - metallic_roughness.setFormat( pickMetallicFormat() ); - metallic_roughness.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); - metallic_roughness.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); - - // RGB - auto emissive { builder.attachment( EMISSIVE_INDEX ) }; - emissive.setFormat( pickEmissiveFormat() ); - emissive.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); - emissive.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); - - auto composite { builder.attachment( COMPOSITE_INDEX ) }; - //TODO: For HDR I think this needs to be a bigger range then 8bits per channel. - composite.setFormat( pickCompositeFormat() ); // composite - composite.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); - composite.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); - - auto depth { builder.attachment( DEPTH_INDEX ) }; - depth.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilReadOnlyOptimal ); - depth.setFormat( pickDepthFormat() ); // depth - depth.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); - - auto& g_buffer_subpass { builder.createSubpass( 0 ) }; - g_buffer_subpass.setDepthLayout( DEPTH_INDEX, vk::ImageLayout::eDepthStencilAttachmentOptimal ); - g_buffer_subpass.addRenderLayout( COLOR_INDEX, vk::ImageLayout::eColorAttachmentOptimal ); - g_buffer_subpass.addRenderLayout( POSITION_INDEX, vk::ImageLayout::eColorAttachmentOptimal ); - g_buffer_subpass.addRenderLayout( NORMAL_INDEX, vk::ImageLayout::eColorAttachmentOptimal ); - g_buffer_subpass.addRenderLayout( METALLIC_INDEX, vk::ImageLayout::eColorAttachmentOptimal ); - g_buffer_subpass.addRenderLayout( EMISSIVE_INDEX, vk::ImageLayout::eColorAttachmentOptimal ); - - g_buffer_subpass.addDependencyFromExternal( - vk::AccessFlagBits::eDepthStencilAttachmentWrite, - vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests ); - - g_buffer_subpass.addDependencyFromExternal( - vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput ); - - auto& composite_subpass { builder.createSubpass( 1 ) }; - composite_subpass.addRenderLayout( COMPOSITE_INDEX, vk::ImageLayout::eColorAttachmentOptimal ); - composite_subpass.addInputLayout( COLOR_INDEX, vk::ImageLayout::eShaderReadOnlyOptimal ); - composite_subpass.addInputLayout( POSITION_INDEX, vk::ImageLayout::eShaderReadOnlyOptimal ); - composite_subpass.addInputLayout( NORMAL_INDEX, vk::ImageLayout::eShaderReadOnlyOptimal ); - composite_subpass.addInputLayout( METALLIC_INDEX, vk::ImageLayout::eShaderReadOnlyOptimal ); - composite_subpass.addInputLayout( EMISSIVE_INDEX, vk::ImageLayout::eShaderReadOnlyOptimal ); - - composite_subpass.addDependency( - g_buffer_subpass, - vk::AccessFlagBits::eColorAttachmentWrite, - vk::PipelineStageFlagBits::eColorAttachmentOutput, - vk::AccessFlagBits::eInputAttachmentRead, - vk::PipelineStageFlagBits::eFragmentShader ); - - composite_subpass.addDependencyFromExternal( - vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput ); - - return builder.create(); - } - - void CameraRenderer::setViewport( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent ) - { - vk::Viewport viewport {}; - viewport.x = 0.0f; - viewport.y = 0.0f; - viewport.width = static_cast< float >( extent.width ); - viewport.height = static_cast< float >( extent.height ); - - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - - const std::vector< vk::Viewport > viewports { viewport }; - - command_buffer.setViewport( 0, viewports ); - } - - void CameraRenderer::setScissor( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent ) - { - const vk::Rect2D scissor { { 0, 0 }, extent }; - - const std::vector< vk::Rect2D > scissors { scissor }; - - command_buffer.setScissor( 0, scissors ); - } - - void CameraRenderer::beginRenderPass( - const vk::raii::CommandBuffer& command_buffer, CameraSwapchain& swapchain, const FrameIndex index ) - { - const vk::RenderingInfo info { swapchain.getRenderingInfo( index ) }; - - command_buffer.beginRendering( info ); - - /* - vk::RenderPassBeginInfo info {}; - info.renderPass = m_renderpass; - info.framebuffer = swapchain.getFramebuffer( index ); - info.renderArea = { .offset = { 0, 0 }, .extent = swapchain.getExtent() }; - - info.setClearValues( swapchain.getClearValues() ); - */ - - // command_buffer.beginRenderPass( info, vk::SubpassContents::eInline ); - - setViewport( command_buffer, swapchain.getExtent() ); - setScissor( command_buffer, swapchain.getExtent() ); - } - - void CameraRenderer::endRenderPass( const vk::raii::CommandBuffer& command_buffer ) - { - command_buffer.endRendering(); - // command_buffer.endRenderPass(); - } - - void CameraRenderer::pass( FrameInfo& frame_info, CameraSwapchain& camera_swapchain ) - { - ZoneScopedN( "CameraRenderer::pass" ); - m_culling_system.startPass( frame_info ); - - auto& command_buffer { frame_info.command_buffer }; - - camera_swapchain.transitionImages( command_buffer, CameraSwapchain::INITAL, frame_info.frame_idx ); - - beginRenderPass( command_buffer, camera_swapchain, frame_info.frame_idx ); - - // Transition the gbuffer to it's inital state - - m_culling_system.wait(); - - //m_terrain_system.pass( frame_info ); - - m_entity_renderer.pass( frame_info ); - m_line_drawer.pass( frame_info ); - - endRenderPass( command_buffer ); - - m_composition_system.pass( frame_info ); - } - - vk::raii::RenderPass& CameraRenderer::getRenderpass() - { - return m_renderpass; - } - -} // namespace fgl::engine diff --git a/src/engine/camera/CameraSwapchain.cpp b/src/engine/camera/CameraSwapchain.cpp deleted file mode 100644 index 780f37c..0000000 --- a/src/engine/camera/CameraSwapchain.cpp +++ /dev/null @@ -1,284 +0,0 @@ -// -// Created by kj16609 on 7/11/24. -// - -#include "CameraSwapchain.hpp" - -#include "engine/descriptors/DescriptorSet.hpp" - -namespace fgl::engine -{ - - std::vector< std::unique_ptr< descriptors::DescriptorSet > > CameraSwapchain::createGBufferDescriptors() - { - std::vector< std::unique_ptr< descriptors::DescriptorSet > > data {}; - data.resize( SwapChain::MAX_FRAMES_IN_FLIGHT ); - - for ( PresentIndex i = 0; i < SwapChain::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::eShaderReadOnlyOptimal ); - - set->bindAttachment( 1, m_gbuffer.m_position.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - - set->bindAttachment( 2, m_gbuffer.m_normal.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - - set->bindAttachment( 3, m_gbuffer.m_metallic.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - - set->bindAttachment( 4, m_gbuffer.m_emissive.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - - set->update(); - - data[ i ] = std::move( set ); - } - - return data; - } - - vk::ImageMemoryBarrier createColorImageBarrier( - const Image& image, - const vk::ImageLayout old_layout, - const vk::ImageLayout new_layout, - const vk::AccessFlags flags ) - { - vk::ImageMemoryBarrier barrier {}; - - barrier.setImage( image.getVkImage() ); - barrier.setOldLayout( old_layout ); - barrier.setNewLayout( new_layout ); - barrier.setSrcAccessMask( flags ); - - constexpr vk::ImageSubresourceRange subresource { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 }; - - barrier.setSubresourceRange( subresource ); - - return barrier; - } - - vk::ImageMemoryBarrier createDepthImageBarrier( - const Image& image, const vk::ImageLayout old_layout, const vk::ImageLayout new_layout ) - { - vk::ImageMemoryBarrier barrier {}; - barrier.setImage( image.getVkImage() ); - barrier.setOldLayout( old_layout ); - barrier.setNewLayout( new_layout ); - constexpr vk::ImageSubresourceRange subresource { - vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1, - }; - - barrier.setSubresourceRange( subresource ); - return barrier; - } - - void CameraSwapchain::transitionImages( - vk::raii::CommandBuffer& command_buffer, const std::uint16_t stage_id, const FrameIndex index ) - { - switch ( stage_id ) - { - default: - throw std::invalid_argument( "Invalid Stage ID" ); - case INITAL: - { - const std::vector< vk::ImageMemoryBarrier > barriers { - createColorImageBarrier( - m_gbuffer.m_color.getImage( index ), - vk::ImageLayout::eUndefined, - vk::ImageLayout::eColorAttachmentOptimal, - vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ), - createColorImageBarrier( - m_gbuffer.m_emissive.getImage( index ), - vk::ImageLayout::eUndefined, - vk::ImageLayout::eColorAttachmentOptimal, - vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ), - createColorImageBarrier( - m_gbuffer.m_metallic.getImage( index ), - vk::ImageLayout::eUndefined, - vk::ImageLayout::eColorAttachmentOptimal, - vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ), - createColorImageBarrier( - m_gbuffer.m_position.getImage( index ), - vk::ImageLayout::eUndefined, - vk::ImageLayout::eColorAttachmentOptimal, - vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ), - createDepthImageBarrier( - m_gbuffer.m_depth.getImage( index ), - vk::ImageLayout::eUndefined, - vk::ImageLayout::eDepthStencilAttachmentOptimal ) - }; - - command_buffer.pipelineBarrier( - vk::PipelineStageFlagBits::eColorAttachmentOutput, - vk::PipelineStageFlagBits::eBottomOfPipe, - vk::DependencyFlags( 0 ), - {}, - {}, - barriers ); - - return; - } - case FINAL: - { - return; - } - } - } - - vk::RenderingInfo CameraSwapchain::getRenderingInfo( const FrameIndex frame_index ) - { - // This should be safe to have as static as the information used here will only capable of being used in a single frame. - static thread_local std::vector< vk::RenderingAttachmentInfo > color_attachment_infos {}; - static thread_local vk::RenderingAttachmentInfo depth_attachment_infos {}; - - depth_attachment_infos = m_gbuffer.m_depth.renderInfo( frame_index, vk::ImageLayout::eDepthAttachmentOptimal ); - - color_attachment_infos.clear(); - color_attachment_infos = { - m_gbuffer.m_color.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ), - m_gbuffer.m_position.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ), - m_gbuffer.m_normal.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ), - m_gbuffer.m_metallic.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ), - m_gbuffer.m_emissive.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ) - }; - - vk::RenderingInfo rendering_info {}; - - rendering_info.setRenderArea( { { 0, 0 }, m_extent } ); - - rendering_info.setLayerCount( 1 ); - - rendering_info.setColorAttachments( color_attachment_infos ); - rendering_info.setPDepthAttachment( &depth_attachment_infos ); - // rendering_info.setPStencilAttachment( &depth_attachment_infos ); - - return rendering_info; - } - - const std::vector< vk::ClearValue >& CameraSwapchain::getClearValues() - { - assert( !m_clear_values.empty() ); - return m_clear_values; - } - - std::vector< vk::raii::Framebuffer > CameraSwapchain::createFrambuffers() - { - constexpr auto image_count { SwapChain::MAX_FRAMES_IN_FLIGHT }; - - m_gbuffer.m_color.createResources( image_count, m_extent ); - m_gbuffer.m_position.createResources( image_count, m_extent ); - m_gbuffer.m_normal.createResources( image_count, m_extent ); - m_gbuffer.m_metallic.createResources( image_count, m_extent ); - m_gbuffer.m_emissive.createResources( image_count, m_extent ); - - m_gbuffer.m_composite.createResources( image_count, m_extent, vk::ImageUsageFlagBits::eTransferSrc ); - m_gbuffer.m_depth.createResources( image_count, m_extent ); - m_gbuffer.m_depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) ); - - std::vector< vk::raii::Framebuffer > buffers {}; - buffers.reserve( image_count ); - - for ( FrameIndex i = 0; i < image_count; ++i ) - { - std::vector< vk::ImageView > attachments { getViewsForFrame( - i, - m_gbuffer.m_color, - m_gbuffer.m_position, - m_gbuffer.m_normal, - m_gbuffer.m_metallic, - m_gbuffer.m_emissive, - m_gbuffer.m_composite, - m_gbuffer.m_depth ) }; - - vk::FramebufferCreateInfo info {}; - info.renderPass = m_renderpass; - info.setAttachments( attachments ); - info.width = m_extent.width; - info.height = m_extent.height; - info.layers = 1; - - buffers.emplace_back( Device::getInstance()->createFramebuffer( info ) ); - - m_g_buffer_color_img.emplace_back( - std::make_unique< Texture >( m_gbuffer.m_color.m_attachment_resources.m_images[ i ] - ->setName( "GBufferColor" ) ) ); - - auto& position_resources { m_gbuffer.m_position.m_attachment_resources }; - assert( position_resources.m_images[ i ] ); - assert( position_resources.m_image_views[ i ] ); - auto& position_image { *position_resources.m_images[ i ] }; - position_image.setName( format_ns::format( "GBufferPosition: {}", i ) ); - m_g_buffer_position_img.emplace_back( std::make_unique< Texture >( position_image ) ); - - m_g_buffer_normal_img.emplace_back( - std::make_unique< Texture >( m_gbuffer.m_normal.m_attachment_resources.m_images[ i ] - ->setName( "GBufferNormal" ) ) ); - - m_g_buffer_metallic_img.emplace_back( - std::make_unique< Texture >( m_gbuffer.m_metallic.m_attachment_resources.m_images[ i ] - ->setName( "GBufferMetallic" ) ) ); - - m_g_buffer_emissive_img.emplace_back( - std::make_unique< Texture >( m_gbuffer.m_emissive.m_attachment_resources.m_images[ i ] - ->setName( "GBufferEmissive" ) ) ); - - m_g_buffer_composite_img.emplace_back( - std::make_unique< Texture >( m_gbuffer.m_composite.m_attachment_resources.m_images[ i ] - ->setName( "GBufferComposite" ) ) ); - } - - return buffers; - } - - descriptors::DescriptorSet& CameraSwapchain::getGBufferDescriptor( const FrameIndex frame_index ) - { - return *m_gbuffer_descriptor_set[ frame_index ]; - } - - vk::raii::Framebuffer& CameraSwapchain::getFramebuffer( const FrameIndex frame_index ) - { - return m_framebuffers[ frame_index ]; - } - - vk::Extent2D CameraSwapchain::getExtent() const - { - return m_extent; - } - - Image& CameraSwapchain::getOutput( const FrameIndex index ) - { - assert( index <= this->m_gbuffer.m_composite.m_attachment_resources.m_images.size() ); - return *m_gbuffer.m_composite.m_attachment_resources.m_images[ index ]; - } - - float CameraSwapchain::getAspectRatio() - { - return static_cast< float >( m_extent.width ) / static_cast< float >( m_extent.height ); - } - - CameraSwapchain::CameraSwapchain( vk::raii::RenderPass& renderpass, const vk::Extent2D extent ) : - m_extent( extent ), - m_renderpass( renderpass ), - m_framebuffers( createFrambuffers() ), - m_clear_values( gatherClearValues( - m_gbuffer.m_color, - m_gbuffer.m_position, - m_gbuffer.m_normal, - m_gbuffer.m_metallic, - m_gbuffer.m_emissive, - m_gbuffer.m_composite, - m_gbuffer.m_depth ) ), - m_gbuffer_descriptor_set( createGBufferDescriptors() ) - { - m_gbuffer.m_depth.setName( "Depth" ); - } - - CameraSwapchain::~CameraSwapchain() - { - for ( auto& descriptor : m_gbuffer_descriptor_set ) - { - descriptors::queueDescriptorDeletion( std::move( descriptor ) ); - } - } - -} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/camera/CompositeSwapchain.cpp b/src/engine/camera/CompositeSwapchain.cpp new file mode 100644 index 0000000..301df29 --- /dev/null +++ b/src/engine/camera/CompositeSwapchain.cpp @@ -0,0 +1,91 @@ +// +// Created by kj16609 on 1/13/25. +// +#include "CompositeSwapchain.hpp" + +#include "engine/rendering/SwapChain.hpp" +#include "engine/rendering/pipelines/Attachment.hpp" + +namespace fgl::engine +{ + class Texture; + + void CompositeSwapchain:: + transitionImages( vk::raii::CommandBuffer& command_buffer, StageID stage_id, FrameIndex index ) + { + switch ( stage_id ) + { + default: + throw std::runtime_error( "Invalid StageID" ); + case INITAL: + { + const std::vector< vk::ImageMemoryBarrier > barriers { + m_buffer.m_target.getImage( index ) + .transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ), + }; + + command_buffer.pipelineBarrier( + vk::PipelineStageFlagBits::eTopOfPipe, + vk::PipelineStageFlagBits::eColorAttachmentOutput, + vk::DependencyFlags( 0 ), + {}, + {}, + barriers ); + + return; + } + case FINAL: + { + const std::vector< vk::ImageMemoryBarrier > barriers { + m_buffer.m_target.getImage( index ).transitionColorTo( + vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::ePresentSrcKHR ), + }; + + command_buffer.pipelineBarrier( + vk::PipelineStageFlagBits::eColorAttachmentOutput, + vk::PipelineStageFlagBits::eBottomOfPipe, + vk::DependencyFlags( 0 ), + {}, + {}, + barriers ); + + return; + } + } + } + + vk::RenderingInfo CompositeSwapchain::getRenderingInfo( const FrameIndex index ) + { + static thread_local std::vector< vk::RenderingAttachmentInfo > infos {}; + + infos.clear(); + + infos = { m_buffer.m_target.renderInfo( index, vk::ImageLayout::eColorAttachmentOptimal ) }; + + vk::RenderingInfo rendering_info {}; + + rendering_info.setRenderArea( { { 0, 0 }, m_extent } ); + + rendering_info.setLayerCount( 1 ); + + rendering_info.setColorAttachments( infos ); + + return rendering_info; + } + + CompositeSwapchain::CompositeSwapchain( vk::Extent2D extent ) : m_extent( extent ) + { + constexpr auto image_count { SwapChain::MAX_FRAMES_IN_FLIGHT }; + + m_buffer.m_target.createResources( image_count, m_extent, vk::ImageUsageFlagBits::eTransferSrc ); + + for ( const auto& image : m_buffer.m_target.m_attachment_resources.m_images ) + { + m_gbuffer_target.emplace_back( std::make_unique< Texture >( *image ) ); + } + } + + CompositeSwapchain::~CompositeSwapchain() + {} + +} // namespace fgl::engine diff --git a/src/engine/camera/CompositeSwapchain.hpp b/src/engine/camera/CompositeSwapchain.hpp new file mode 100644 index 0000000..f1b54bc --- /dev/null +++ b/src/engine/camera/CompositeSwapchain.hpp @@ -0,0 +1,44 @@ +// +// Created by kj16609 on 1/13/25. +// +#pragma once +#include "engine/rendering/RenderingFormats.hpp" +#include "engine/rendering/pipelines/Attachment.hpp" + +namespace fgl::engine +{ + class Texture; + + class CompositeSwapchain + { + vk::Extent2D m_extent; + + struct + { + ColorAttachment< 0 > m_target { pickCompositeFormat() }; + } m_buffer {}; + + public: + + FGL_DELETE_COPY( CompositeSwapchain ); + FGL_DELETE_MOVE( CompositeSwapchain ); + + std::vector< std::unique_ptr< Texture > > m_gbuffer_target {}; + + enum StageID : std::uint16_t + { + INITAL, + FINAL, + }; + + void transitionImages( vk::raii::CommandBuffer& command_buffer, StageID stage_id, FrameIndex index ); + + vk::RenderingInfo getRenderingInfo( FrameIndex index ); + + vk::Extent2D getExtent() const { return m_extent; } + + CompositeSwapchain( vk::Extent2D extent ); + ~CompositeSwapchain(); + }; + +} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/camera/GBufferCompositor.cpp b/src/engine/camera/GBufferCompositor.cpp new file mode 100644 index 0000000..5171f47 --- /dev/null +++ b/src/engine/camera/GBufferCompositor.cpp @@ -0,0 +1,99 @@ +// +// Created by kj16609 on 1/13/25. +// +#include "GBufferCompositor.hpp" + +#include "Camera.hpp" +#include "CompositeSwapchain.hpp" +#include "GBufferSwapchain.hpp" +#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp" + +namespace fgl::engine +{ + + void GBufferCompositor::setViewport( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent ) + { + vk::Viewport viewport {}; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = static_cast< float >( extent.width ); + viewport.height = static_cast< float >( extent.height ); + + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + + const std::vector< vk::Viewport > viewports { viewport }; + + command_buffer.setViewport( 0, viewports ); + } + + void GBufferCompositor::setScissor( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent ) + { + const vk::Rect2D scissor { { 0, 0 }, extent }; + + const std::vector< vk::Rect2D > scissors { scissor }; + + command_buffer.setScissor( 0, scissors ); + } + + void GBufferCompositor:: + beginPass( vk::raii::CommandBuffer& cmd, CompositeSwapchain& swapchain, const FrameIndex& index ) + { + const vk::RenderingInfo info { swapchain.getRenderingInfo( index ) }; + + cmd.beginRendering( info ); + + setViewport( cmd, swapchain.getExtent() ); + setScissor( cmd, swapchain.getExtent() ); + } + + void GBufferCompositor::endPass( vk::raii::CommandBuffer& cmd ) + { + cmd.endRendering(); + } + + GBufferCompositor::GBufferCompositor( const CompositeFlags flags ) : m_flags( flags ) + { + PipelineBuilder builder { 0 }; + + builder.addDescriptorSet( gbuffer_set ); + builder.addDescriptorSet( Camera::getDescriptorLayout() ); + + builder.addColorAttachment().setFormat( pickColorFormat() ).finish(); + + builder.setPushConstant( vk::ShaderStageFlagBits::eFragment, sizeof( CompositionControl ) ); + + builder.setVertexShader( Shader::loadVertex( "shaders/fullscreen.vert" ) ); + builder.setFragmentShader( Shader::loadFragment( "shaders/composition.frag" ) ); + + builder.disableCulling(); + builder.disableVertexInput(); + + m_pipeline = builder.create(); + + m_pipeline->setDebugName( "Composition pipeline" ); + } + + void GBufferCompositor:: + composite( vk::raii::CommandBuffer& command_buffer, Camera& camera, const FrameIndex frame_index ) + { + auto& gbuffer_swapchain { camera.getSwapchain() }; + auto& composite_swapchain { camera.getCompositeSwapchain() }; + + composite_swapchain.transitionImages( command_buffer, CompositeSwapchain::INITAL, frame_index ); + + beginPass( command_buffer, composite_swapchain, frame_index ); + + m_pipeline->bind( command_buffer ); + + m_pipeline->bindDescriptor( command_buffer, gbuffer_swapchain.getGBufferDescriptor( frame_index ) ); + m_pipeline->bindDescriptor( command_buffer, camera.getDescriptor( frame_index ) ); + + m_pipeline->pushConstant( command_buffer, vk::ShaderStageFlagBits::eFragment, m_control ); + + command_buffer.draw( 3, 1, 0, 0 ); + + endPass( command_buffer ); + } + +} // namespace fgl::engine diff --git a/src/engine/camera/GBufferCompositor.hpp b/src/engine/camera/GBufferCompositor.hpp new file mode 100644 index 0000000..31e8b90 --- /dev/null +++ b/src/engine/camera/GBufferCompositor.hpp @@ -0,0 +1,56 @@ +// +// Created by kj16609 on 1/13/25. +// +#pragma once + +#include + +#include "Camera.hpp" +#include "engine/rendering/pipelines/v2/Pipeline.hpp" +#include "engine/rendering/types.hpp" +#include "engine/systems/composition/Control.hpp" + +namespace fgl::engine +{ + class CompositeSwapchain; + class Image; + class GBufferSwapchain; + using CompositeFlags = std::uint16_t; + + enum CompositeFlagBits : CompositeFlags + { + CompositeFlagBits_None = 0, + CompositeFlagBits_NormalOnly = 1 << 0, + //! The final output should be transformed into a presenting valid format. + CompositeFlagBits_PresentTarget = 1 << 1, + + CompositeFlagBits_Standard = CompositeFlagBits_None, + }; + + /** + * @brief Composites a GBuffer input + */ + class GBufferCompositor + { + CompositeFlags m_flags; + + std::unique_ptr< Pipeline > m_pipeline { nullptr }; + + void setViewport( const vk::raii::CommandBuffer& cmd, vk::Extent2D extent_2d ); + void setScissor( const vk::raii::CommandBuffer& cmd, vk::Extent2D extent_2d ); + + void beginPass( vk::raii::CommandBuffer& cmd, CompositeSwapchain& swapchain, const FrameIndex& index ); + void endPass( vk::raii::CommandBuffer& cmd ); + + CompositionControl m_control {}; + + public: + + GBufferCompositor( CompositeFlags flags = CompositeFlagBits_Standard ); + + void composite( vk::raii::CommandBuffer& command_buffer, Camera& camera, FrameIndex frame_index ); + + inline void switchMode( const CompositeFlags flags ) { m_flags = flags; } + }; + +} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/camera/GBufferRenderer.cpp b/src/engine/camera/GBufferRenderer.cpp new file mode 100644 index 0000000..ad5d09c --- /dev/null +++ b/src/engine/camera/GBufferRenderer.cpp @@ -0,0 +1,82 @@ +// +// Created by kj16609 on 7/21/24. +// + +#include "GBufferRenderer.hpp" + +#include "Camera.hpp" +#include "engine/rendering/renderpass/RenderPass.hpp" + +namespace fgl::engine +{ + class GBufferSwapchain; + + void GBufferRenderer::setViewport( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent ) + { + vk::Viewport viewport {}; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = static_cast< float >( extent.width ); + viewport.height = static_cast< float >( extent.height ); + + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + + const std::vector< vk::Viewport > viewports { viewport }; + + command_buffer.setViewport( 0, viewports ); + } + + void GBufferRenderer::setScissor( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent ) + { + const vk::Rect2D scissor { { 0, 0 }, extent }; + + const std::vector< vk::Rect2D > scissors { scissor }; + + command_buffer.setScissor( 0, scissors ); + } + + void GBufferRenderer::beginRenderPass( + const vk::raii::CommandBuffer& command_buffer, GBufferSwapchain& swapchain, const FrameIndex index ) + { + const vk::RenderingInfo info { swapchain.getRenderingInfo( index ) }; + + command_buffer.beginRendering( info ); + + setViewport( command_buffer, swapchain.getExtent() ); + setScissor( command_buffer, swapchain.getExtent() ); + } + + void GBufferRenderer::endRenderPass( const vk::raii::CommandBuffer& command_buffer ) + { + command_buffer.endRendering(); + } + + void GBufferRenderer::pass( FrameInfo& frame_info, GBufferSwapchain& camera_swapchain ) + { + ZoneScopedN( "CameraRenderer::pass" ); + m_culling_system.startPass( frame_info ); + + auto& command_buffer { frame_info.command_buffer }; + + camera_swapchain.transitionImages( command_buffer, GBufferSwapchain::INITAL, frame_info.frame_idx ); + + beginRenderPass( command_buffer, camera_swapchain, frame_info.frame_idx ); + + // Transition the gbuffer to it's inital state + + m_culling_system.wait(); + + //m_terrain_system.pass( frame_info ); + + m_entity_renderer.pass( frame_info ); + m_line_drawer.pass( frame_info ); + + endRenderPass( command_buffer ); + + camera_swapchain.transitionImages( command_buffer, GBufferSwapchain::FINAL, frame_info.frame_idx ); + + m_compositor.composite( command_buffer, *frame_info.camera, frame_info.frame_idx ); + } + +} // namespace fgl::engine diff --git a/src/engine/camera/CameraRenderer.hpp b/src/engine/camera/GBufferRenderer.hpp similarity index 52% rename from src/engine/camera/CameraRenderer.hpp rename to src/engine/camera/GBufferRenderer.hpp index fa1fd78..74a983d 100644 --- a/src/engine/camera/CameraRenderer.hpp +++ b/src/engine/camera/GBufferRenderer.hpp @@ -4,8 +4,8 @@ #pragma once -#include "CameraSwapchain.hpp" -#include "engine/systems/composition/CompositionSystem.hpp" +#include "GBufferCompositor.hpp" +#include "GBufferSwapchain.hpp" #include "engine/systems/prerender/CullingSystem.hpp" #include "engine/systems/render/EntityRendererSystem.hpp" #include "engine/systems/render/LineDrawer.hpp" @@ -13,11 +13,10 @@ namespace fgl::engine { - class CameraRenderer + class GBufferRenderer { - vk::raii::RenderPass m_renderpass; + GBufferCompositor m_compositor; - static vk::raii::RenderPass createRenderPass(); void setViewport( const vk::raii::CommandBuffer& command_buffer, vk::Extent2D extent ); void setScissor( const vk::raii::CommandBuffer& command_buffer, vk::Extent2D extent ); @@ -25,24 +24,22 @@ namespace fgl::engine // SubPass 0 //TerrainSystem m_terrain_system { Device::getInstance(), m_renderpass }; - EntityRendererSystem m_entity_renderer { m_renderpass }; - LineDrawer m_line_drawer { m_renderpass }; + EntityRendererSystem m_entity_renderer {}; + LineDrawer m_line_drawer {}; // SubPass 1 - CompositionSystem m_composition_system { m_renderpass }; + // CompositionSystem m_composition_system {}; void beginRenderPass( - const vk::raii::CommandBuffer& command_buffer, CameraSwapchain& swapchain, const FrameIndex index ); + const vk::raii::CommandBuffer& command_buffer, GBufferSwapchain& swapchain, FrameIndex index ); void endRenderPass( const vk::raii::CommandBuffer& command_buffer ); public: - void pass( FrameInfo& frame_info, CameraSwapchain& camera_swapchain ); + void pass( FrameInfo& frame_info, GBufferSwapchain& camera_swapchain ); - vk::raii::RenderPass& getRenderpass(); - - CameraRenderer() : m_renderpass( createRenderPass() ) {} + GBufferRenderer() = default; }; } // namespace fgl::engine diff --git a/src/engine/camera/GBufferSwapchain.cpp b/src/engine/camera/GBufferSwapchain.cpp new file mode 100644 index 0000000..b2b9515 --- /dev/null +++ b/src/engine/camera/GBufferSwapchain.cpp @@ -0,0 +1,189 @@ +// +// Created by kj16609 on 7/11/24. +// + +#include "GBufferSwapchain.hpp" + +#include "engine/descriptors/DescriptorSet.hpp" + +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 ); + + for ( PresentIndex i = 0; i < SwapChain::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( 1, m_gbuffer.m_position.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR ); + + set->bindAttachment( 2, m_gbuffer.m_normal.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR ); + + set->bindAttachment( 3, m_gbuffer.m_metallic.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR ); + + set->bindAttachment( 4, m_gbuffer.m_emissive.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR ); + + set->update(); + + data[ i ] = std::move( set ); + } + + return data; + } + + void GBufferSwapchain::transitionImages( + vk::raii::CommandBuffer& command_buffer, const std::uint16_t stage_id, const FrameIndex index ) + { + switch ( stage_id ) + { + default: + throw std::invalid_argument( "Invalid Stage ID" ); + case INITAL: + { + const std::vector< vk::ImageMemoryBarrier > barriers { + m_gbuffer.m_color.getImage( index ) + .transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ), + m_gbuffer.m_emissive.getImage( index ) + .transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ), + m_gbuffer.m_metallic.getImage( index ) + .transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ), + m_gbuffer.m_position.getImage( index ) + .transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ), + m_gbuffer.m_normal.getImage( index ) + .transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ), + m_gbuffer.m_depth.getImage( index ).transitionTo( + vk::ImageLayout::eUndefined, + vk::ImageLayout::eDepthAttachmentOptimal, + 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: + { + // Final should turn all of these into readonly in order to be used for other render targets. + const std::vector< vk::ImageMemoryBarrier > barriers { + m_gbuffer.m_color.getImage( index ).transitionColorTo( + vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ), + m_gbuffer.m_emissive.getImage( index ).transitionColorTo( + vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ), + m_gbuffer.m_metallic.getImage( index ).transitionColorTo( + vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ), + m_gbuffer.m_position.getImage( index ).transitionColorTo( + vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ), + m_gbuffer.m_normal.getImage( index ).transitionColorTo( + vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ) + // It might be useful to properly transition this for other post processing effects later + // m_gbuffer.m_depth.getImage( index ).transitionTo( + // vk::ImageLayout::eDepthAttachmentOptimal, + // vk::ImageLayout::eDepthReadOnlyOptimal, + // vk::ImageAspectFlagBits::eDepth ), + }; + + command_buffer.pipelineBarrier( + vk::PipelineStageFlagBits::eColorAttachmentOutput, + vk::PipelineStageFlagBits::eFragmentShader, + vk::DependencyFlags( 0 ), + {}, + {}, + barriers ); + + return; + } + } + } + + vk::RenderingInfo GBufferSwapchain::getRenderingInfo( const FrameIndex frame_index ) + { + // This should be safe to have as static as the information used here will only capable of being used in a single frame. + static thread_local std::vector< vk::RenderingAttachmentInfo > color_attachment_infos {}; + static thread_local vk::RenderingAttachmentInfo depth_attachment_infos {}; + + depth_attachment_infos = m_gbuffer.m_depth.renderInfo( frame_index, vk::ImageLayout::eDepthAttachmentOptimal ); + + color_attachment_infos.clear(); + color_attachment_infos = { + m_gbuffer.m_color.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ), + m_gbuffer.m_position.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ), + m_gbuffer.m_normal.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ), + m_gbuffer.m_metallic.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ), + m_gbuffer.m_emissive.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ) + }; + + vk::RenderingInfo rendering_info {}; + + rendering_info.setRenderArea( { { 0, 0 }, m_extent } ); + + rendering_info.setLayerCount( 1 ); + + rendering_info.setColorAttachments( color_attachment_infos ); + rendering_info.setPDepthAttachment( &depth_attachment_infos ); + // rendering_info.setPStencilAttachment( &depth_attachment_infos ); + + return rendering_info; + } + + descriptors::DescriptorSet& GBufferSwapchain::getGBufferDescriptor( const FrameIndex frame_index ) + { + return *m_gbuffer_descriptor_set[ frame_index ]; + } + + vk::Extent2D GBufferSwapchain::getExtent() const + { + return m_extent; + } + + float GBufferSwapchain::getAspectRatio() + { + return static_cast< float >( m_extent.width ) / static_cast< float >( m_extent.height ); + } + + GBufferSwapchain::GBufferSwapchain( const vk::Extent2D extent ) : m_extent( extent ) + // m_gbuffer_descriptor_set( createGBufferDescriptors() ) + { + constexpr auto image_count { SwapChain::MAX_FRAMES_IN_FLIGHT }; + + m_gbuffer.m_color.createResources( image_count, m_extent ); + m_gbuffer.m_position.createResources( image_count, m_extent ); + m_gbuffer.m_normal.createResources( image_count, m_extent ); + m_gbuffer.m_metallic.createResources( image_count, m_extent ); + m_gbuffer.m_emissive.createResources( image_count, m_extent ); + + m_gbuffer.m_depth.createResources( image_count, m_extent ); + m_gbuffer.m_depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) ); + + m_gbuffer.m_color.setName( "Color" ); + m_gbuffer.m_position.setName( "Position" ); + m_gbuffer.m_normal.setName( "Normal" ); + m_gbuffer.m_metallic.setName( "Metallic" ); + m_gbuffer.m_emissive.setName( "Emissive" ); + m_gbuffer.m_depth.setName( "Depth" ); + + m_gbuffer_descriptor_set = createGBufferDescriptors(); + } + + GBufferSwapchain::~GBufferSwapchain() + { + for ( auto& descriptor : m_gbuffer_descriptor_set ) + { + descriptors::queueDescriptorDeletion( std::move( descriptor ) ); + } + } + +} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/camera/CameraSwapchain.hpp b/src/engine/camera/GBufferSwapchain.hpp similarity index 60% rename from src/engine/camera/CameraSwapchain.hpp rename to src/engine/camera/GBufferSwapchain.hpp index 09a8b5c..46590b8 100644 --- a/src/engine/camera/CameraSwapchain.hpp +++ b/src/engine/camera/GBufferSwapchain.hpp @@ -21,7 +21,7 @@ namespace fgl::engine constexpr std::size_t COMPOSITE_INDEX { 5 }; constexpr std::size_t DEPTH_INDEX { 6 }; - class CameraSwapchain + class GBufferSwapchain { struct { @@ -30,31 +30,16 @@ namespace fgl::engine ColorAttachment< NORMAL_INDEX > m_normal { pickNormalFormat() }; ColorAttachment< METALLIC_INDEX > m_metallic { pickMetallicFormat() }; ColorAttachment< EMISSIVE_INDEX > m_emissive { pickEmissiveFormat() }; - - ColorAttachment< COMPOSITE_INDEX > m_composite { pickCompositeFormat() }; + //TODO: Move depth into m_position A channel DepthAttachment< DEPTH_INDEX > m_depth { pickDepthFormat() }; + + // ColorAttachment< COMPOSITE_INDEX > m_composite { pickCompositeFormat() }; } m_gbuffer {}; - public: - - std::vector< std::unique_ptr< Texture > > m_g_buffer_color_img {}; - std::vector< std::unique_ptr< Texture > > m_g_buffer_position_img {}; - std::vector< std::unique_ptr< Texture > > m_g_buffer_normal_img {}; - std::vector< std::unique_ptr< Texture > > m_g_buffer_metallic_img {}; - std::vector< std::unique_ptr< Texture > > m_g_buffer_emissive_img {}; - - std::vector< std::unique_ptr< Texture > > m_g_buffer_composite_img {}; - private: vk::Extent2D m_extent; - vk::raii::RenderPass& m_renderpass; - - std::vector< vk::raii::Framebuffer > m_framebuffers; - - 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 > > createGBufferDescriptors(); @@ -63,28 +48,21 @@ namespace fgl::engine enum StageID : std::uint16_t { - INITAL = 0, - FINAL = std::numeric_limits< std::uint16_t >::max() + INITAL, + COMPOSITE, + FINAL }; void transitionImages( vk::raii::CommandBuffer& command_buffer, std::uint16_t stage_id, FrameIndex index ); vk::RenderingInfo getRenderingInfo( const FrameIndex frame_index ); - CameraSwapchain( vk::raii::RenderPass& renderpass, vk::Extent2D extent ); - ~CameraSwapchain(); - - const std::vector< vk::ClearValue >& getClearValues(); - - std::vector< vk::raii::Framebuffer > createFrambuffers(); + GBufferSwapchain( vk::Extent2D extent ); + ~GBufferSwapchain(); descriptors::DescriptorSet& getGBufferDescriptor( FrameIndex frame_index ); - vk::raii::Framebuffer& getFramebuffer( FrameIndex frame_index ); - vk::Extent2D getExtent() const; - Image& getOutput( const FrameIndex index ); - float getAspectRatio(); }; diff --git a/src/engine/rendering/Instance.cpp b/src/engine/rendering/Instance.cpp index cdf17e9..9d75517 100644 --- a/src/engine/rendering/Instance.cpp +++ b/src/engine/rendering/Instance.cpp @@ -99,7 +99,7 @@ namespace fgl::engine info.pEngineName = "titor"; info.engineVersion = VK_MAKE_VERSION( 1, 0, 0 ); - info.apiVersion = VK_API_VERSION_1_4; + info.apiVersion = VK_API_VERSION_1_3; return info; } diff --git a/src/engine/rendering/RenderProcess.puml b/src/engine/rendering/RenderProcess.puml new file mode 100644 index 0000000..0d1c9eb --- /dev/null +++ b/src/engine/rendering/RenderProcess.puml @@ -0,0 +1,24 @@ +@startuml +'https://plantuml.com/sequence-diagram + +autonumber + + +box "GBuffer" #LightBlue +participant Depth +participant Albedo +participant Depth + + +end box + + +Alice -> Bob: Authentication Request +Bob --> Alice: Authentication Response + +Alice -> Bob: Another authentication Request +Alice <-- Bob: another authentication Response + + + +@enduml \ No newline at end of file diff --git a/src/engine/rendering/devices/Device.cpp b/src/engine/rendering/devices/Device.cpp index 5ffeb4c..b1f4e4e 100644 --- a/src/engine/rendering/devices/Device.cpp +++ b/src/engine/rendering/devices/Device.cpp @@ -75,6 +75,8 @@ namespace fgl::engine { m_dynamic_rendering_features.setDynamicRendering( VK_TRUE ); m_dynamic_rendering_local_read_features.setDynamicRenderingLocalRead( VK_TRUE ); + m_dynamic_rendering_unused_features.setDynamicRenderingUnusedAttachments( VK_TRUE ); + m_info_chain.unlink< vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT >(); } std::vector< vk::DeviceQueueCreateInfo > Device::DeviceCreateInfo:: diff --git a/src/engine/rendering/devices/Device.hpp b/src/engine/rendering/devices/Device.hpp index d1a577c..01157de 100644 --- a/src/engine/rendering/devices/Device.hpp +++ b/src/engine/rendering/devices/Device.hpp @@ -51,7 +51,8 @@ namespace fgl::engine using InfoChain = vk::StructureChain< vk::DeviceCreateInfo, vk::PhysicalDeviceDynamicRenderingFeatures, - vk::PhysicalDeviceDynamicRenderingLocalReadFeatures, + vk::PhysicalDeviceDynamicRenderingLocalReadFeaturesKHR, + vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT, vk::PhysicalDeviceDescriptorIndexingFeatures >; InfoChain m_info_chain; @@ -70,14 +71,18 @@ namespace fgl::engine m_info_chain.get< vk::PhysicalDeviceDescriptorIndexingFeatures >() }; - vk::PhysicalDeviceDynamicRenderingLocalReadFeatures& m_dynamic_rendering_local_read_features { - m_info_chain.get< vk::PhysicalDeviceDynamicRenderingLocalReadFeatures >() + vk::PhysicalDeviceDynamicRenderingLocalReadFeaturesKHR& m_dynamic_rendering_local_read_features { + m_info_chain.get< vk::PhysicalDeviceDynamicRenderingLocalReadFeaturesKHR >() }; vk::PhysicalDeviceDynamicRenderingFeatures& m_dynamic_rendering_features { m_info_chain.get< vk::PhysicalDeviceDynamicRenderingFeatures >() }; + vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT& m_dynamic_rendering_unused_features { + m_info_chain.get< vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT >() + }; + DeviceCreateInfo( PhysicalDevice& ); } device_creation_info; diff --git a/src/engine/rendering/pipelines/Attachment.hpp b/src/engine/rendering/pipelines/Attachment.hpp index e37028e..5c7d04d 100644 --- a/src/engine/rendering/pipelines/Attachment.hpp +++ b/src/engine/rendering/pipelines/Attachment.hpp @@ -109,7 +109,7 @@ namespace fgl::engine } //! Creates a resource that is used across all frames - void createResourceSpread( + void createSharedResources( const std::uint32_t count, vk::Extent2D extent, vk::ImageUsageFlags extra_flags = vk::ImageUsageFlags( 0 ) ) { auto image { std::make_shared< Image >( diff --git a/src/engine/systems/composition/CompositionSystem.cpp b/src/engine/systems/composition/CompositionSystem.cpp deleted file mode 100644 index e4127e8..0000000 --- a/src/engine/systems/composition/CompositionSystem.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// -// Created by kj16609 on 3/11/24. -// - -#include "CompositionSystem.hpp" - -#include "Control.hpp" -#include "editor/src/gui/safe_include.hpp" -#include "engine/camera/Camera.hpp" -#include "engine/rendering/RenderingFormats.hpp" -#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp" -#include "engine/rendering/pipelines/v2/Pipeline.hpp" -#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp" - -namespace fgl::engine -{ - - CompositionSystem::CompositionSystem( vk::raii::RenderPass& render_pass ) - { - PipelineBuilder builder { 0 }; - - builder.addDescriptorSet( gbuffer_set ); - builder.addDescriptorSet( Camera::getDescriptorLayout() ); - - builder.addColorAttachment().setFormat( pickColorFormat() ).finish(); - - builder.setPushConstant( vk::ShaderStageFlagBits::eFragment, sizeof( CompositionControl ) ); - - builder.setVertexShader( Shader::loadVertex( "shaders/fullscreen.vert" ) ); - builder.setFragmentShader( Shader::loadFragment( "shaders/composition.frag" ) ); - - builder.disableCulling(); - builder.disableVertexInput(); - - m_composite_pipeline = builder.create(); - - m_composite_pipeline->setDebugName( "Composition pipeline" ); - } - - CompositionSystem::~CompositionSystem() - {} - - vk::raii::CommandBuffer& CompositionSystem::setupSystem( FrameInfo& info ) - { - auto& command_buffer { info.command_buffer }; - - m_composite_pipeline->bind( command_buffer ); - - m_composite_pipeline->bindDescriptor( command_buffer, info.getGBufferDescriptor() ); - m_composite_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() ); - - ImGui::Begin( "Composition" ); - - ImGui::InputInt( "Selection", &m_control.m_flags ); - - ImGui::End(); - - m_composite_pipeline->pushConstant( command_buffer, vk::ShaderStageFlagBits::eFragment, m_control ); - - return info.command_buffer; - } - - void CompositionSystem::pass( FrameInfo& info ) - { - auto& command_buffer { setupSystem( info ) }; - TracyVkZone( info.tracy_ctx, *command_buffer, "Composition Pass" ); - - command_buffer.draw( 3, 1, 0, 0 ); - } - -} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/systems/composition/CompositionSystem.hpp b/src/engine/systems/composition/CompositionSystem.hpp deleted file mode 100644 index 29390ea..0000000 --- a/src/engine/systems/composition/CompositionSystem.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// -// Created by kj16609 on 3/11/24. -// - -#pragma once - -#include "Control.hpp" -#include "engine/FrameInfo.hpp" -#include "engine/systems/concepts.hpp" - -namespace fgl::engine -{ - class Pipeline; - - class CompositionSystem - { - std::unique_ptr< Pipeline > m_composite_pipeline { nullptr }; - - vk::raii::CommandBuffer& setupSystem( FrameInfo& info ); - - CompositionControl m_control {}; - - public: - - CompositionSystem( vk::raii::RenderPass& render_pass ); - ~CompositionSystem(); - - void pass( FrameInfo& info ); - }; - - static_assert( is_system< CompositionSystem > ); - -} // namespace fgl::engine diff --git a/src/engine/systems/render/EntityRendererSystem.cpp b/src/engine/systems/render/EntityRendererSystem.cpp index 8426271..e33d840 100644 --- a/src/engine/systems/render/EntityRendererSystem.cpp +++ b/src/engine/systems/render/EntityRendererSystem.cpp @@ -18,7 +18,7 @@ namespace fgl::engine { - EntityRendererSystem::EntityRendererSystem( vk::raii::RenderPass& render_pass ) + EntityRendererSystem::EntityRendererSystem( ) { ZoneScoped; diff --git a/src/engine/systems/render/EntityRendererSystem.hpp b/src/engine/systems/render/EntityRendererSystem.hpp index a8e0989..5811f5d 100644 --- a/src/engine/systems/render/EntityRendererSystem.hpp +++ b/src/engine/systems/render/EntityRendererSystem.hpp @@ -50,7 +50,7 @@ namespace fgl::engine void texturelessPass( const FrameInfo& info ); void texturedPass( const FrameInfo& info ); - EntityRendererSystem( vk::raii::RenderPass& render_pass ); + EntityRendererSystem(); ~EntityRendererSystem(); EntityRendererSystem( EntityRendererSystem&& other ) = delete; EntityRendererSystem( const EntityRendererSystem& other ) = delete; diff --git a/src/engine/systems/render/LineDrawer.cpp b/src/engine/systems/render/LineDrawer.cpp index ea3d810..711e4b6 100644 --- a/src/engine/systems/render/LineDrawer.cpp +++ b/src/engine/systems/render/LineDrawer.cpp @@ -24,7 +24,7 @@ namespace fgl::engine inline static std::vector< VertexLine > m_lines {}; - LineDrawer::LineDrawer( vk::raii::RenderPass& render_pass ) + LineDrawer::LineDrawer( ) { PipelineBuilder builder { 0 }; diff --git a/src/engine/systems/render/LineDrawer.hpp b/src/engine/systems/render/LineDrawer.hpp index 08b4f09..de5bad0 100644 --- a/src/engine/systems/render/LineDrawer.hpp +++ b/src/engine/systems/render/LineDrawer.hpp @@ -22,12 +22,13 @@ namespace fgl::engine public: - FGL_DELETE_ALL_RO5( LineDrawer ); + FGL_DELETE_COPY( LineDrawer ); + FGL_DELETE_MOVE( LineDrawer ); vk::raii::CommandBuffer& setupSystem( FrameInfo& info ); void pass( FrameInfo& info ); - LineDrawer( vk::raii::RenderPass& render_pass ); + LineDrawer(); ~LineDrawer(); };