Finish dynamic rendering changes

This commit is contained in:
2025-01-20 09:58:33 -05:00
parent 14f32aa069
commit 2e9e08a185
35 changed files with 434 additions and 364 deletions

View File

@@ -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)

View File

@@ -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,

View File

@@ -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"

View File

@@ -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 {};

View File

@@ -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 {};

View File

@@ -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 ) };

View File

@@ -4,9 +4,9 @@
#pragma once
#include <memory>
#include <vulkan/vulkan.hpp>
#include "engine/assets/image/ImageHandle.hpp"
#include <memory>
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 );
}

View File

@@ -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

View File

@@ -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; }

View File

@@ -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 ] );

View File

@@ -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;

View File

@@ -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 )
{

View File

@@ -2,6 +2,9 @@
// Created by kj16609 on 1/13/25.
//
#pragma once
#include <vulkan/vulkan_raii.hpp>
#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 );

View File

@@ -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

View File

@@ -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 );

View File

@@ -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

View File

@@ -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

View File

@@ -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();

View File

@@ -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 );
}

View File

@@ -1,4 +1,4 @@
#include "SwapChain.hpp"
#include "PresentSwapChain.hpp"
#include <array>
#include <cstdlib>
@@ -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 );
}

View File

@@ -0,0 +1,114 @@
#pragma once
#include <memory>
#include <vector>
#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

View File

@@ -4,6 +4,7 @@
#include "QueuePool.hpp"
#include "Surface.hpp"
#include "pipelines/Attachment.hpp"
namespace fgl::engine

View File

@@ -11,12 +11,14 @@
#include <iostream>
#include <stdexcept>
#include "SwapChain.hpp"
#include "PresentSwapChain.hpp"
#include "engine/Window.hpp"
//clang-format: off
#include <tracy/TracyVulkan.hpp>
#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

View File

@@ -9,7 +9,7 @@
#include <cassert>
#include <memory>
#include "SwapChain.hpp"
#include "PresentSwapChain.hpp"
//clang-format: off
#include <tracy/TracyVulkan.hpp>
@@ -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 );

View File

@@ -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

View File

@@ -14,5 +14,6 @@ namespace fgl::engine
vk::Format pickMetallicFormat();
vk::Format pickEmissiveFormat();
vk::Format pickCompositeFormat();
vk::Format pickPresentFormat();
} // namespace fgl::engine

View File

@@ -1,115 +0,0 @@
#pragma once
#include <memory>
#include <vector>
#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

View File

@@ -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;
};

View File

@@ -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" );
}
}

View File

@@ -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
{

View File

@@ -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" );

View File

@@ -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 );
};

View File

@@ -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
{

View File

@@ -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
{