Rework swapchain to no longer init inside of ctor body
This commit is contained in:
@@ -30,8 +30,8 @@ namespace fgl::engine
|
||||
a.linkImage( std::declval< std::uint16_t >(), std::declval< Image& >() )
|
||||
};
|
||||
{
|
||||
a.resources()
|
||||
} -> std::same_as< AttachmentResources >;
|
||||
a.getView( std::declval< std::uint8_t >() )
|
||||
} -> std::same_as< ImageView& >;
|
||||
{
|
||||
a.m_clear_value
|
||||
} -> std::same_as< vk::ClearValue& >;
|
||||
|
||||
@@ -76,6 +76,7 @@ namespace fgl::engine
|
||||
|
||||
void linkImages( std::vector< Image >& images )
|
||||
{
|
||||
assert( images.size() > 0 );
|
||||
for ( std::uint16_t i = 0; i < images.size(); ++i )
|
||||
{
|
||||
linkImage( i, images[ i ] );
|
||||
@@ -115,7 +116,11 @@ namespace fgl::engine
|
||||
}
|
||||
}
|
||||
|
||||
AttachmentResources resources() { return m_attachment_resources; }
|
||||
ImageView& getView( std::uint8_t frame_idx )
|
||||
{
|
||||
assert( frame_idx < m_attachment_resources.m_image_views.size() );
|
||||
return *m_attachment_resources.m_image_views[ frame_idx ];
|
||||
}
|
||||
|
||||
vk::AttachmentDescription& desc() { return description; }
|
||||
|
||||
@@ -127,7 +132,7 @@ namespace fgl::engine
|
||||
return index;
|
||||
}
|
||||
|
||||
friend class RenderPass;
|
||||
friend class RenderPassBuilder;
|
||||
};
|
||||
|
||||
template < is_attachment AttachmentT, vk::ImageLayout layout >
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 12/30/23.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Subpass.hpp"
|
||||
#include "engine/image/ImageView.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
struct RenderPassResources
|
||||
{
|
||||
std::vector< std::vector< std::shared_ptr< ImageView > > > m_image_views;
|
||||
|
||||
RenderPassResources() = delete;
|
||||
RenderPassResources( const RenderPassResources& ) = delete;
|
||||
|
||||
RenderPassResources( std::vector< std::vector< std::shared_ptr< ImageView > > >&& image_views ) :
|
||||
m_image_views( std::move( image_views ) )
|
||||
{}
|
||||
|
||||
std::vector< vk::ImageView > forFrame( std::uint32_t frame ) const
|
||||
{
|
||||
std::vector< vk::ImageView > views;
|
||||
|
||||
for ( auto& view : m_image_views.at( frame ) ) views.push_back( view->getVkView() );
|
||||
|
||||
return views;
|
||||
}
|
||||
};
|
||||
|
||||
class RenderPass
|
||||
{
|
||||
std::vector< vk::AttachmentDescription > attachment_descriptions {};
|
||||
std::vector< vk::ClearValue > m_clear_values {};
|
||||
|
||||
std::vector< vk::SubpassDescription > subpass_descriptions {};
|
||||
std::vector< vk::SubpassDependency > dependencies {};
|
||||
|
||||
std::vector< AttachmentResources > m_attachment_resources {};
|
||||
|
||||
public:
|
||||
|
||||
std::vector< vk::ClearValue > getClearValues() const { return m_clear_values; }
|
||||
|
||||
template < typename SubpassT >
|
||||
requires is_subpass< SubpassT >
|
||||
void registerSubpass( SubpassT& subpass )
|
||||
{
|
||||
subpass_descriptions.emplace_back( subpass.description() );
|
||||
|
||||
for ( auto& dependency : subpass.dependencies )
|
||||
{
|
||||
dependencies.push_back( dependency );
|
||||
}
|
||||
}
|
||||
|
||||
template < is_attachment... Attachments >
|
||||
void registerAttachments( Attachments&... attachments )
|
||||
{
|
||||
attachment_descriptions.reserve( sizeof...( Attachments ) );
|
||||
m_clear_values.reserve( sizeof...( Attachments ) );
|
||||
|
||||
( ( attachments.setIndex( static_cast< std::uint32_t >( attachment_descriptions.size() ) ),
|
||||
attachment_descriptions.push_back( attachments.desc() ),
|
||||
m_clear_values.push_back( attachments.m_clear_value ) ),
|
||||
... );
|
||||
|
||||
m_attachment_resources.reserve( sizeof...( Attachments ) );
|
||||
|
||||
( ( m_attachment_resources.emplace_back( attachments.m_attachment_resources ) ), ... );
|
||||
}
|
||||
|
||||
std::unique_ptr< RenderPassResources > resources( std::uint16_t frame_count )
|
||||
{
|
||||
assert( m_attachment_resources.size() > 0 && "Must register attachments before getting resources" );
|
||||
|
||||
//Each attachment will have a vector of image views, one for each frame
|
||||
// We need to seperate them out so that we have a vector of image views for each frame
|
||||
std::vector< std::vector< std::shared_ptr< ImageView > > > views;
|
||||
|
||||
views.resize( frame_count );
|
||||
|
||||
for ( auto& attachment : m_attachment_resources )
|
||||
{
|
||||
assert(
|
||||
attachment.m_image_views.size() == frame_count
|
||||
&& "Attachment image views must be equal to frame count" );
|
||||
for ( std::uint16_t frame_idx = 0; frame_idx < attachment.m_image_views.size(); ++frame_idx )
|
||||
{
|
||||
views[ frame_idx ].emplace_back( attachment.m_image_views[ frame_idx ] );
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_unique< RenderPassResources >( std::move( views ) );
|
||||
}
|
||||
|
||||
vk::raii::RenderPass create();
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -2,14 +2,13 @@
|
||||
// Created by kj16609 on 12/31/23.
|
||||
//
|
||||
|
||||
#include "RenderPass.hpp"
|
||||
|
||||
#include "Device.hpp"
|
||||
#include "RenderPassBuilder.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
vk::raii::RenderPass RenderPass::create()
|
||||
vk::raii::RenderPass RenderPassBuilder::create()
|
||||
{
|
||||
auto& device { Device::getInstance() };
|
||||
|
||||
52
src/engine/rendering/RenderPassBuilder.hpp
Normal file
52
src/engine/rendering/RenderPassBuilder.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Created by kj16609 on 12/30/23.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Subpass.hpp"
|
||||
#include "engine/image/ImageView.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
class RenderPassBuilder
|
||||
{
|
||||
std::vector< vk::AttachmentDescription > attachment_descriptions {};
|
||||
std::vector< vk::ClearValue > m_clear_values {};
|
||||
|
||||
std::vector< vk::SubpassDescription > subpass_descriptions {};
|
||||
std::vector< vk::SubpassDependency > dependencies {};
|
||||
|
||||
public:
|
||||
|
||||
std::vector< vk::ClearValue > getClearValues() const { return m_clear_values; }
|
||||
|
||||
template < typename SubpassT >
|
||||
requires is_subpass< SubpassT >
|
||||
void registerSubpass( SubpassT& subpass )
|
||||
{
|
||||
subpass_descriptions.emplace_back( subpass.description() );
|
||||
|
||||
for ( auto& dependency : subpass.dependencies )
|
||||
{
|
||||
dependencies.push_back( dependency );
|
||||
}
|
||||
}
|
||||
|
||||
template < is_attachment... Attachments >
|
||||
void registerAttachments( Attachments&... attachments )
|
||||
{
|
||||
attachment_descriptions.reserve( sizeof...( Attachments ) );
|
||||
m_clear_values.reserve( sizeof...( Attachments ) );
|
||||
|
||||
( ( attachments.setIndex( static_cast< std::uint32_t >( attachment_descriptions.size() ) ),
|
||||
attachment_descriptions.push_back( attachments.desc() ),
|
||||
m_clear_values.push_back( attachments.m_clear_value ) ),
|
||||
... );
|
||||
}
|
||||
|
||||
vk::raii::RenderPass create();
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -109,7 +109,7 @@ namespace fgl::engine
|
||||
|
||||
vk::SubpassDescription description() { return subpass_description; }
|
||||
|
||||
friend class RenderPass;
|
||||
friend class RenderPassBuilder;
|
||||
|
||||
void registerDependency(
|
||||
std::uint32_t src_subpass,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Attachment.hpp"
|
||||
#include "RenderPass.hpp"
|
||||
#include "RenderPassBuilder.hpp"
|
||||
#include "Subpass.hpp"
|
||||
#include "engine/assets/TransferManager.hpp"
|
||||
|
||||
@@ -26,7 +26,18 @@ namespace fgl::engine
|
||||
old_swap_chain( nullptr ),
|
||||
m_swapchain( createSwapChain() ),
|
||||
m_swap_chain_images( createSwapchainImages() ),
|
||||
render_attachments( getSwapChainImageFormat(), findDepthFormat() )
|
||||
render_attachments( getSwapChainImageFormat(), findDepthFormat() ),
|
||||
m_render_pass( createRenderPass() ),
|
||||
m_swap_chain_buffers( createFramebuffers() ),
|
||||
m_clear_values( gatherClearValues(
|
||||
render_attachments.color,
|
||||
render_attachments.depth,
|
||||
gbuffer.position,
|
||||
gbuffer.normal,
|
||||
gbuffer.albedo,
|
||||
gbuffer.composite ) ),
|
||||
m_gbuffer_descriptor_set( createGBufferDescriptors() ),
|
||||
m_gbuffer_composite_descriptor_set( createCompositeDescriptors() )
|
||||
{
|
||||
init();
|
||||
}
|
||||
@@ -42,7 +53,18 @@ namespace fgl::engine
|
||||
old_swap_chain( previous ),
|
||||
m_swapchain( createSwapChain() ),
|
||||
m_swap_chain_images( createSwapchainImages() ),
|
||||
render_attachments( getSwapChainImageFormat(), findDepthFormat() )
|
||||
render_attachments( getSwapChainImageFormat(), findDepthFormat() ),
|
||||
m_render_pass( createRenderPass() ),
|
||||
m_swap_chain_buffers( createFramebuffers() ),
|
||||
m_clear_values( gatherClearValues(
|
||||
render_attachments.color,
|
||||
render_attachments.depth,
|
||||
gbuffer.position,
|
||||
gbuffer.normal,
|
||||
gbuffer.albedo,
|
||||
gbuffer.composite ) ),
|
||||
m_gbuffer_descriptor_set( createGBufferDescriptors() ),
|
||||
m_gbuffer_composite_descriptor_set( createCompositeDescriptors() )
|
||||
{
|
||||
init();
|
||||
old_swap_chain.reset();
|
||||
@@ -50,8 +72,6 @@ namespace fgl::engine
|
||||
|
||||
void SwapChain::init()
|
||||
{
|
||||
createRenderPass();
|
||||
createFramebuffers();
|
||||
createSyncObjects();
|
||||
}
|
||||
|
||||
@@ -67,7 +87,7 @@ namespace fgl::engine
|
||||
|
||||
auto result { m_swapchain.acquireNextImage(
|
||||
std::numeric_limits< uint64_t >::max(),
|
||||
imageAvailableSemaphores[ m_current_frame_index ] // must be a not signaled semaphore
|
||||
image_available_sem[ m_current_frame_index ] // must be a not signaled semaphore
|
||||
) };
|
||||
|
||||
return result;
|
||||
@@ -87,7 +107,7 @@ namespace fgl::engine
|
||||
|
||||
vk::SubmitInfo m_submit_info {};
|
||||
|
||||
std::vector< vk::Semaphore > wait_sems { imageAvailableSemaphores[ m_current_frame_index ],
|
||||
std::vector< vk::Semaphore > wait_sems { image_available_sem[ m_current_frame_index ],
|
||||
memory::TransferManager::getInstance().getFinishedSem() };
|
||||
|
||||
std::vector< vk::PipelineStageFlags > wait_stages { vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
||||
@@ -99,7 +119,7 @@ namespace fgl::engine
|
||||
m_submit_info.commandBufferCount = 1;
|
||||
m_submit_info.pCommandBuffers = &( *buffers );
|
||||
|
||||
std::vector< vk::Semaphore > signaled_semaphores { renderFinishedSemaphores[ m_current_frame_index ] };
|
||||
std::vector< vk::Semaphore > signaled_semaphores { render_finished_sem[ m_current_frame_index ] };
|
||||
m_submit_info.setSignalSemaphores( signaled_semaphores );
|
||||
|
||||
Device::getInstance().device().resetFences( fences );
|
||||
@@ -201,45 +221,18 @@ namespace fgl::engine
|
||||
return images;
|
||||
}
|
||||
|
||||
void SwapChain::createRenderPass()
|
||||
vk::raii::RenderPass SwapChain::createRenderPass()
|
||||
{
|
||||
ZoneScoped;
|
||||
//Present attachment
|
||||
|
||||
for ( int i = 0; i < imageCount(); ++i )
|
||||
{
|
||||
auto& image { m_swap_chain_images[ i ] };
|
||||
|
||||
image.setName( "SwapChainImage: " + std::to_string( i ) );
|
||||
}
|
||||
|
||||
render_attachments.color.linkImages( m_swap_chain_images );
|
||||
|
||||
gbuffer.position.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
|
||||
gbuffer.normal.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
|
||||
gbuffer.albedo.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
|
||||
gbuffer.composite.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
|
||||
|
||||
render_attachments.depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) );
|
||||
gbuffer.position.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) );
|
||||
gbuffer.normal.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) );
|
||||
gbuffer.albedo.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) );
|
||||
gbuffer.composite.setClear( vk::ClearColorValue( std::array< float, 4 > { { 0.0f, 0.0f, 0.0f, 0.0f } } ) );
|
||||
|
||||
g_buffer_position_img = std::make_unique< Texture >( gbuffer.position.m_attachment_resources.m_images[ 0 ]
|
||||
->setName( "GBufferPosition" ) );
|
||||
g_buffer_normal_img = std::make_unique< Texture >( gbuffer.normal.m_attachment_resources.m_images[ 0 ]
|
||||
->setName( "GBufferNormal" ) );
|
||||
g_buffer_albedo_img = std::make_unique< Texture >( gbuffer.albedo.m_attachment_resources.m_images[ 0 ]
|
||||
->setName( "GBufferAlbedo" ) );
|
||||
g_buffer_composite_img = std::make_unique< Texture >( gbuffer.composite.m_attachment_resources.m_images[ 0 ]
|
||||
->setName( "GBufferComposite" ) );
|
||||
|
||||
RenderPass render_pass {};
|
||||
|
||||
render_attachments.depth.createResources( imageCount(), getSwapChainExtent() );
|
||||
render_attachments.depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) );
|
||||
|
||||
render_pass.registerAttachments(
|
||||
render_pass_builder.registerAttachments(
|
||||
render_attachments.color,
|
||||
render_attachments.depth,
|
||||
gbuffer.position,
|
||||
@@ -247,50 +240,6 @@ namespace fgl::engine
|
||||
gbuffer.albedo,
|
||||
gbuffer.composite );
|
||||
|
||||
for ( int i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
|
||||
{
|
||||
{
|
||||
auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) };
|
||||
|
||||
set->setMaxIDX( 2 );
|
||||
|
||||
set->bindAttachment(
|
||||
0,
|
||||
*( gbuffer.position.resources().m_image_views[ i ].get() ),
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->bindAttachment(
|
||||
1,
|
||||
*( gbuffer.normal.resources().m_image_views[ i ].get() ),
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->bindAttachment(
|
||||
2,
|
||||
*( gbuffer.albedo.resources().m_image_views[ i ].get() ),
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->update();
|
||||
|
||||
m_gbuffer_descriptor_set[ i ] = std::move( set );
|
||||
}
|
||||
|
||||
{
|
||||
auto composite_set {
|
||||
std::make_unique< descriptors::DescriptorSet >( GBufferCompositeDescriptorSet::createLayout() )
|
||||
};
|
||||
|
||||
composite_set->setMaxIDX( 1 );
|
||||
composite_set->bindAttachment(
|
||||
0,
|
||||
*( gbuffer.composite.resources().m_image_views[ i ].get() ),
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
composite_set->update();
|
||||
|
||||
m_gbuffer_composite_descriptor_set[ i ] = std::move( composite_set );
|
||||
}
|
||||
}
|
||||
|
||||
static_assert( is_attachment< ColoredPresentAttachment > );
|
||||
static_assert( is_attachment< DepthAttachment > );
|
||||
|
||||
@@ -341,16 +290,6 @@ namespace fgl::engine
|
||||
vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests,
|
||||
vk::DependencyFlagBits::eByRegion );
|
||||
|
||||
/*
|
||||
composite_subpass.registerDependencyFrom(
|
||||
g_buffer_subpass,
|
||||
vk::AccessFlagBits::eColorAttachmentWrite,
|
||||
vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
||||
vk::AccessFlagBits::eTransferWrite,
|
||||
vk::PipelineStageFlagBits::eTopOfPipe,
|
||||
vk::DependencyFlagBits::eByRegion );
|
||||
*/
|
||||
|
||||
// To prevent the composite buffer from getting obliterated by the gui pass and so we can use it to render to the GUI in certian areas, We need to keep them seperate and the composite image to be unmodified.
|
||||
Subpass<
|
||||
vk::PipelineBindPoint::eGraphics,
|
||||
@@ -362,10 +301,6 @@ namespace fgl::engine
|
||||
gui_subpass.registerDependencyFromExternal(
|
||||
vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput );
|
||||
|
||||
/*
|
||||
g_buffer_subpass -> composite_subpass -> gui_subpass
|
||||
*/
|
||||
|
||||
gui_subpass.registerDependencyFrom(
|
||||
composite_subpass,
|
||||
vk::AccessFlagBits::eColorAttachmentWrite,
|
||||
@@ -374,9 +309,6 @@ namespace fgl::engine
|
||||
vk::PipelineStageFlagBits::eFragmentShader,
|
||||
vk::DependencyFlagBits::eByRegion );
|
||||
|
||||
//composite_subpass.registerFullDependency( g_buffer_subpass );
|
||||
//gui_subpass.registerFullDependency( composite_subpass );
|
||||
|
||||
gui_subpass.registerDependencyFrom(
|
||||
composite_subpass,
|
||||
vk::AccessFlagBits::eColorAttachmentWrite,
|
||||
@@ -392,24 +324,51 @@ namespace fgl::engine
|
||||
vk::PipelineStageFlagBits::eBottomOfPipe,
|
||||
vk::DependencyFlagBits::eByRegion );
|
||||
|
||||
render_pass.registerSubpass( g_buffer_subpass );
|
||||
render_pass.registerSubpass( composite_subpass );
|
||||
render_pass.registerSubpass( gui_subpass );
|
||||
render_pass_builder.registerSubpass( g_buffer_subpass );
|
||||
render_pass_builder.registerSubpass( composite_subpass );
|
||||
render_pass_builder.registerSubpass( gui_subpass );
|
||||
|
||||
m_render_pass = render_pass.create();
|
||||
m_clear_values = render_pass_builder.getClearValues();
|
||||
|
||||
m_render_pass_resources = render_pass.resources( imageCount() );
|
||||
m_clear_values = render_pass.getClearValues();
|
||||
return render_pass_builder.create();
|
||||
}
|
||||
|
||||
void SwapChain::createFramebuffers()
|
||||
std::vector< vk::raii::Framebuffer > SwapChain::createFramebuffers()
|
||||
{
|
||||
ZoneScoped;
|
||||
m_swap_chain_buffers.clear();
|
||||
m_swap_chain_buffers.reserve( imageCount() );
|
||||
|
||||
render_attachments.depth.createResources( imageCount(), getSwapChainExtent() );
|
||||
|
||||
render_attachments.color.linkImages( m_swap_chain_images );
|
||||
|
||||
gbuffer.position.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
|
||||
gbuffer.normal.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
|
||||
gbuffer.albedo.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
|
||||
gbuffer.composite.createResourceSpread( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eSampled );
|
||||
|
||||
g_buffer_position_img = std::make_unique< Texture >( gbuffer.position.m_attachment_resources.m_images[ 0 ]
|
||||
->setName( "GBufferPosition" ) );
|
||||
g_buffer_normal_img = std::make_unique< Texture >( gbuffer.normal.m_attachment_resources.m_images[ 0 ]
|
||||
->setName( "GBufferNormal" ) );
|
||||
g_buffer_albedo_img = std::make_unique< Texture >( gbuffer.albedo.m_attachment_resources.m_images[ 0 ]
|
||||
->setName( "GBufferAlbedo" ) );
|
||||
g_buffer_composite_img = std::make_unique< Texture >( gbuffer.composite.m_attachment_resources.m_images[ 0 ]
|
||||
->setName( "GBufferComposite" ) );
|
||||
|
||||
std::vector< vk::raii::Framebuffer > framebuffers {};
|
||||
|
||||
framebuffers.reserve( imageCount() );
|
||||
|
||||
for ( uint8_t i = 0; i < imageCount(); i++ )
|
||||
{
|
||||
std::vector< vk::ImageView > attachments { m_render_pass_resources->forFrame( i ) };
|
||||
std::vector< vk::ImageView > attachments { getViewsForFrame(
|
||||
i,
|
||||
render_attachments.color,
|
||||
render_attachments.depth,
|
||||
gbuffer.position,
|
||||
gbuffer.normal,
|
||||
gbuffer.albedo,
|
||||
gbuffer.composite ) };
|
||||
|
||||
//Fill attachments for this frame
|
||||
const vk::Extent2D swapChainExtent { getSwapChainExtent() };
|
||||
@@ -421,15 +380,17 @@ namespace fgl::engine
|
||||
framebufferInfo.height = swapChainExtent.height;
|
||||
framebufferInfo.layers = 1;
|
||||
|
||||
m_swap_chain_buffers.push_back( Device::getInstance()->createFramebuffer( framebufferInfo ) );
|
||||
framebuffers.push_back( Device::getInstance()->createFramebuffer( framebufferInfo ) );
|
||||
}
|
||||
|
||||
return framebuffers;
|
||||
}
|
||||
|
||||
void SwapChain::createSyncObjects()
|
||||
{
|
||||
ZoneScoped;
|
||||
imageAvailableSemaphores.reserve( MAX_FRAMES_IN_FLIGHT );
|
||||
renderFinishedSemaphores.reserve( MAX_FRAMES_IN_FLIGHT );
|
||||
image_available_sem.reserve( MAX_FRAMES_IN_FLIGHT );
|
||||
render_finished_sem.reserve( MAX_FRAMES_IN_FLIGHT );
|
||||
in_flight_fence.reserve( MAX_FRAMES_IN_FLIGHT );
|
||||
images_in_flight.resize( imageCount(), VK_NULL_HANDLE );
|
||||
|
||||
@@ -442,8 +403,8 @@ namespace fgl::engine
|
||||
{
|
||||
auto& device { Device::getInstance() };
|
||||
|
||||
imageAvailableSemaphores.push_back( device->createSemaphore( semaphoreInfo ) );
|
||||
renderFinishedSemaphores.push_back( device->createSemaphore( semaphoreInfo ) );
|
||||
image_available_sem.push_back( device->createSemaphore( semaphoreInfo ) );
|
||||
render_finished_sem.push_back( device->createSemaphore( semaphoreInfo ) );
|
||||
in_flight_fence.push_back( device->createFence( fenceInfo ) );
|
||||
}
|
||||
}
|
||||
@@ -534,6 +495,53 @@ namespace fgl::engine
|
||||
}
|
||||
}
|
||||
|
||||
std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > SwapChain::
|
||||
createGBufferDescriptors()
|
||||
{
|
||||
std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > data;
|
||||
|
||||
for ( int i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
|
||||
{
|
||||
auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) };
|
||||
|
||||
set->setMaxIDX( 2 );
|
||||
|
||||
set->bindAttachment( 0, gbuffer.position.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->bindAttachment( 1, gbuffer.normal.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->bindAttachment( 2, gbuffer.albedo.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->update();
|
||||
|
||||
data[ i ] = std::move( set );
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > SwapChain::
|
||||
createCompositeDescriptors()
|
||||
{
|
||||
std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT > data;
|
||||
|
||||
for ( int i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
|
||||
{
|
||||
auto composite_set {
|
||||
std::make_unique< descriptors::DescriptorSet >( GBufferCompositeDescriptorSet::createLayout() )
|
||||
};
|
||||
|
||||
composite_set->setMaxIDX( 1 );
|
||||
composite_set->bindAttachment( 0, gbuffer.composite.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
composite_set->update();
|
||||
|
||||
data[ i ] = std::move( composite_set );
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
vk::Format SwapChain::findDepthFormat()
|
||||
{
|
||||
ZoneScoped;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Device.hpp"
|
||||
#include "RenderPass.hpp"
|
||||
#include "RenderPassBuilder.hpp"
|
||||
#include "engine/FrameInfo.hpp"
|
||||
#include "engine/texture/Texture.hpp"
|
||||
|
||||
@@ -49,18 +49,6 @@ namespace fgl::engine
|
||||
ColorAttachment composite { vk::Format::eR8G8B8A8Unorm };
|
||||
} gbuffer {};
|
||||
|
||||
std::vector< vk::raii::Framebuffer > m_swap_chain_buffers {};
|
||||
vk::raii::RenderPass m_render_pass { VK_NULL_HANDLE };
|
||||
std::unique_ptr< RenderPassResources > m_render_pass_resources { nullptr };
|
||||
|
||||
std::vector< vk::raii::Semaphore > imageAvailableSemaphores {};
|
||||
std::vector< vk::raii::Semaphore > renderFinishedSemaphores {};
|
||||
std::vector< vk::raii::Fence > in_flight_fence {};
|
||||
std::vector< vk::Fence > images_in_flight {};
|
||||
size_t m_current_frame_index { 0 };
|
||||
|
||||
std::vector< vk::ClearValue > m_clear_values {};
|
||||
|
||||
public:
|
||||
|
||||
std::unique_ptr< Texture > g_buffer_position_img { nullptr };
|
||||
@@ -70,11 +58,31 @@ namespace fgl::engine
|
||||
|
||||
private:
|
||||
|
||||
RenderPassBuilder render_pass_builder {};
|
||||
|
||||
vk::raii::RenderPass m_render_pass;
|
||||
|
||||
std::vector< vk::raii::Framebuffer > m_swap_chain_buffers;
|
||||
|
||||
std::vector< vk::ClearValue > m_clear_values;
|
||||
|
||||
std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT >
|
||||
m_gbuffer_descriptor_set;
|
||||
|
||||
std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT >
|
||||
m_gbuffer_composite_descriptor_set;
|
||||
|
||||
std::vector< vk::raii::Semaphore > image_available_sem {};
|
||||
std::vector< vk::raii::Semaphore > render_finished_sem {};
|
||||
std::vector< vk::raii::Fence > in_flight_fence {};
|
||||
std::vector< vk::Fence > images_in_flight {};
|
||||
size_t m_current_frame_index { 0 };
|
||||
|
||||
void init();
|
||||
[[nodiscard]] vk::raii::SwapchainKHR createSwapChain();
|
||||
[[nodiscard]] std::vector< Image > createSwapchainImages();
|
||||
void createRenderPass();
|
||||
void createFramebuffers();
|
||||
[[nodiscard]] vk::raii::RenderPass createRenderPass();
|
||||
[[nodiscard]] std::vector< vk::raii::Framebuffer > createFramebuffers();
|
||||
void createSyncObjects();
|
||||
|
||||
// Helper functions
|
||||
@@ -82,11 +90,32 @@ namespace fgl::engine
|
||||
vk::PresentModeKHR chooseSwapPresentMode( const std::vector< vk::PresentModeKHR >& availablePresentModes );
|
||||
vk::Extent2D chooseSwapExtent( const vk::SurfaceCapabilitiesKHR& capabilities );
|
||||
|
||||
std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT >
|
||||
m_gbuffer_descriptor_set {};
|
||||
template < is_attachment... Attachments >
|
||||
static std::vector< vk::ImageView > getViewsForFrame( const std::uint8_t frame_idx, Attachments... attachments )
|
||||
{
|
||||
std::vector< vk::ImageView > view {};
|
||||
view.resize( sizeof...( Attachments ) );
|
||||
|
||||
( ( view[ attachments.getIndex() ] = *attachments.getView( frame_idx ) ), ... );
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
template < is_attachment... Attachments >
|
||||
static std::vector< vk::ClearValue > gatherClearValues( Attachments... attachments )
|
||||
{
|
||||
std::vector< vk::ClearValue > clear_values {};
|
||||
clear_values.resize( sizeof...( Attachments ) );
|
||||
|
||||
( ( clear_values[ attachments.getIndex() ] = attachments.m_clear_value ), ... );
|
||||
|
||||
return clear_values;
|
||||
}
|
||||
|
||||
std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT >
|
||||
m_gbuffer_composite_descriptor_set {};
|
||||
createGBufferDescriptors();
|
||||
std::array< std::unique_ptr< descriptors::DescriptorSet >, SwapChain::MAX_FRAMES_IN_FLIGHT >
|
||||
createCompositeDescriptors();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user