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