Setup command pools for primary and secondary command buffers, Split recording into multiple secondary buffers

This commit is contained in:
2025-02-14 17:20:57 -05:00
parent 129524f8ca
commit bc326e2c79
37 changed files with 615 additions and 162 deletions

View File

@@ -145,16 +145,18 @@ namespace fgl::engine
void EngineContext::renderFrame()
{
ZoneScoped;
if ( auto& command_buffer = m_renderer.beginFrame(); *command_buffer )
if ( auto command_buffers_o = m_renderer.beginFrame(); command_buffers_o.has_value() )
{
const auto timer = debug::timing::push( "Render Frame" );
const FrameIndex frame_index { m_renderer.getFrameIndex() };
const PresentIndex present_idx { m_renderer.getPresentIndex() };
auto& command_buffers { command_buffers_o.value() };
FrameInfo frame_info { frame_index,
present_idx,
m_delta_time,
command_buffer,
command_buffers,
nullptr, // Camera
m_camera_manager.getCameras(),
// global_descriptor_sets[ frame_index ],
@@ -172,25 +174,25 @@ namespace fgl::engine
for ( const auto& hook : m_pre_frame_hooks ) hook( frame_info );
}
TracyVkCollect( frame_info.tracy_ctx, *command_buffer );
TracyVkCollect( frame_info.tracy_ctx, *command_buffers.transfer_cb );
//TODO: Setup semaphores to make this pass not always required.
m_transfer_manager.recordOwnershipTransferDst( command_buffer );
m_transfer_manager.recordOwnershipTransferDst( command_buffers.transfer_cb );
for ( const auto& hook : m_early_render_hooks ) hook( frame_info );
//TODO: Add some way of 'activating' cameras. We don't need to render cameras that aren't active.
renderCameras( frame_info );
for ( const auto& hook : m_render_hooks ) hook( frame_info );
m_renderer.beginSwapchainRendererPass( command_buffer );
m_renderer.beginSwapchainRendererPass( command_buffers.imgui_cb );
m_gui_system.pass( frame_info );
for ( const auto& hook : m_late_render_hooks ) hook( frame_info );
m_renderer.endSwapchainRendererPass( command_buffer );
m_renderer.endSwapchainRendererPass( command_buffers.imgui_cb );
m_renderer.endFrame();
m_renderer.endFrame( command_buffers );
m_transfer_manager.dump();

View File

@@ -12,6 +12,7 @@
#include "descriptors/Descriptor.hpp"
#include "descriptors/DescriptorSetLayout.hpp"
#include "primitives/Frustum.hpp"
#include "rendering/CommandBuffers.hpp"
#include "rendering/types.hpp"
#define MAX_LIGHTS 10
@@ -75,7 +76,7 @@ namespace fgl::engine
PresentIndex present_idx;
double delta_time;
vk::raii::CommandBuffer& command_buffer;
CommandBuffers& command_buffer;
Camera* camera { nullptr };

View File

@@ -54,6 +54,11 @@ namespace fgl::engine::memory
const std::vector< vk::BufferMemoryBarrier > from_memory_barriers { createFromGraphicsBarriers() };
vk::DebugUtilsLabelEXT debug_label {};
debug_label.pLabelName = "Transfer";
command_buffer.beginDebugUtilsLabelEXT( debug_label );
// Acquire the buffer from the queue family
command_buffer.pipelineBarrier(
vk::PipelineStageFlagBits::eBottomOfPipe,
@@ -66,7 +71,7 @@ namespace fgl::engine::memory
//Record all the buffer copies
for ( auto& [ key, regions ] : m_copy_regions )
{
auto& [ source, target ] = key;
const auto& [ source, target ] = key;
command_buffer.copyBuffer( source, target, regions );
}
@@ -81,6 +86,8 @@ namespace fgl::engine::memory
{},
to_buffer_memory_barriers,
{} );
command_buffer.endDebugUtilsLabelEXT();
}
void TransferManager::resizeBuffer( const std::uint64_t size )
@@ -218,21 +225,21 @@ namespace fgl::engine::memory
inline static TransferManager* GLOBAL_TRANSFER_MANAGER {};
void TransferManager::takeOwnership( vk::raii::CommandBuffer& command_buffer )
void TransferManager::takeOwnership( CommandBuffer& command_buffer )
{
std::vector< vk::BufferMemoryBarrier > barriers { createToTransferBarriers() };
command_buffer.pipelineBarrier(
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eNone, vk::PipelineStageFlagBits::eTransfer, {}, {}, barriers, {} );
}
void TransferManager::recordOwnershipTransferDst( vk::raii::CommandBuffer& command_buffer )
void TransferManager::recordOwnershipTransferDst( CommandBuffer& command_buffer )
{
ZoneScoped;
std::vector< vk::BufferMemoryBarrier > barriers { createToGraphicsBarriers() };
command_buffer.pipelineBarrier(
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eTransfer,
vk::PipelineStageFlagBits::eVertexInput | vk::PipelineStageFlagBits::eVertexShader,
{},

View File

@@ -84,10 +84,10 @@ namespace fgl::engine::memory
vk::raii::Semaphore& getFinishedSem() { return m_transfer_semaphore; }
//! Takes ownership of memory regions from the graphics queue via memory barriers.
void takeOwnership( vk::raii::CommandBuffer& buffer );
void takeOwnership( CommandBuffer& command_buffer );
//! Records the barriers required for transfering queue ownership
void recordOwnershipTransferDst( vk::raii::CommandBuffer& command_buffer );
void recordOwnershipTransferDst( CommandBuffer& command_buffer );
//! Drops the processed items
void dump();

View File

@@ -133,6 +133,8 @@ namespace fgl::engine
{
this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
log::debug( "Camera swapchain recreated" );
m_old_composite_swapchain = std::move( m_composite_swapchain );
m_old_gbuffer_swapchain = std::move( m_gbuffer_swapchain );
@@ -335,13 +337,13 @@ namespace fgl::engine
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, PresentSwapChain::MAX_FRAMES_IN_FLIGHT )
m_camera_frame_info( buffer, constants::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 < PresentSwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
for ( std::uint8_t i = 0; i < constants::MAX_FRAMES_IN_FLIGHT; ++i )
{
auto set { camera_descriptor_set.create() };
set->bindUniformBuffer( 0, m_camera_frame_info[ i ] );

View File

@@ -10,8 +10,7 @@ namespace fgl::engine
{
class Texture;
void CompositeSwapchain::
transitionImages( vk::raii::CommandBuffer& command_buffer, StageID stage_id, FrameIndex index )
void CompositeSwapchain::transitionImages( CommandBuffer& command_buffer, StageID stage_id, FrameIndex index )
{
switch ( stage_id )
{
@@ -24,7 +23,7 @@ namespace fgl::engine
.transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ),
};
command_buffer.pipelineBarrier(
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eTopOfPipe,
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::DependencyFlags( 0 ),
@@ -41,7 +40,7 @@ namespace fgl::engine
vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ),
};
command_buffer.pipelineBarrier(
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::PipelineStageFlagBits::eFragmentShader,
vk::DependencyFlags( 0 ),
@@ -58,7 +57,7 @@ namespace fgl::engine
vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::ePresentSrcKHR ),
};
command_buffer.pipelineBarrier(
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::PipelineStageFlagBits::eBottomOfPipe,
vk::DependencyFlags( 0 ),
@@ -94,7 +93,7 @@ namespace fgl::engine
CompositeSwapchain::CompositeSwapchain( vk::Extent2D extent ) : m_extent( extent )
{
constexpr auto image_count { PresentSwapChain::MAX_FRAMES_IN_FLIGHT };
constexpr auto image_count { constants::MAX_FRAMES_IN_FLIGHT };
m_buffer.m_target.createResources( image_count, m_extent, vk::ImageUsageFlagBits::eTransferSrc );
m_buffer.m_target.setName( "CompositeSwapchain::m_target" );

View File

@@ -7,6 +7,7 @@
#include "FGL_DEFINES.hpp"
#include "engine/rendering/RenderingFormats.hpp"
#include "engine/rendering/pipelines/Attachment.hpp"
#include "rendering/CommandBufferPool.hpp"
namespace fgl::engine
{
@@ -35,7 +36,7 @@ namespace fgl::engine
FINAL_PRESENT,
};
void transitionImages( vk::raii::CommandBuffer& command_buffer, StageID stage_id, FrameIndex index );
void transitionImages( CommandBuffer& command_buffer, StageID stage_id, FrameIndex index );
vk::RenderingInfo getRenderingInfo( FrameIndex index );

View File

@@ -36,20 +36,19 @@ namespace fgl::engine
command_buffer.setScissor( 0, scissors );
}
void GBufferCompositor::
beginPass( vk::raii::CommandBuffer& cmd, CompositeSwapchain& swapchain, const FrameIndex& index )
void GBufferCompositor::beginPass( CommandBuffer& cmd, CompositeSwapchain& swapchain, const FrameIndex& index )
{
const vk::RenderingInfo info { swapchain.getRenderingInfo( index ) };
cmd.beginRendering( info );
cmd->beginRendering( info );
setViewport( cmd, swapchain.getExtent() );
setScissor( cmd, swapchain.getExtent() );
setViewport( *cmd, swapchain.getExtent() );
setScissor( *cmd, swapchain.getExtent() );
}
void GBufferCompositor::endPass( vk::raii::CommandBuffer& cmd )
void GBufferCompositor::endPass( CommandBuffer& cmd )
{
cmd.endRendering();
cmd->endRendering();
}
GBufferCompositor::GBufferCompositor( const CompositeFlags flags ) : m_flags( flags )
@@ -74,8 +73,7 @@ namespace fgl::engine
m_pipeline->setDebugName( "Composition pipeline" );
}
void GBufferCompositor::
composite( vk::raii::CommandBuffer& command_buffer, Camera& camera, const FrameIndex frame_index )
void GBufferCompositor::composite( CommandBuffer& command_buffer, Camera& camera, const FrameIndex frame_index )
{
auto& gbuffer_swapchain { camera.getSwapchain() };
auto& composite_swapchain { camera.getCompositeSwapchain() };
@@ -91,7 +89,7 @@ namespace fgl::engine
m_pipeline->pushConstant( command_buffer, vk::ShaderStageFlagBits::eFragment, m_control );
command_buffer.draw( 3, 1, 0, 0 );
command_buffer->draw( 3, 1, 0, 0 );
endPass( command_buffer );

View File

@@ -39,8 +39,8 @@ namespace fgl::engine
void setViewport( const vk::raii::CommandBuffer& cmd, vk::Extent2D extent_2d );
void setScissor( const vk::raii::CommandBuffer& cmd, vk::Extent2D extent_2d );
void beginPass( vk::raii::CommandBuffer& cmd, CompositeSwapchain& swapchain, const FrameIndex& index );
void endPass( vk::raii::CommandBuffer& cmd );
void beginPass( CommandBuffer& cmd, CompositeSwapchain& swapchain, const FrameIndex& index );
void endPass( CommandBuffer& cmd );
CompositionControl m_control {};
@@ -48,7 +48,7 @@ namespace fgl::engine
GBufferCompositor( CompositeFlags flags = CompositeFlagBits_Standard );
void composite( vk::raii::CommandBuffer& command_buffer, Camera& camera, FrameIndex frame_index );
void composite( CommandBuffer& command_buffer, Camera& camera, FrameIndex frame_index );
inline void switchMode( const CompositeFlags flags ) { m_flags = flags; }
};

View File

@@ -5,13 +5,14 @@
#include "GBufferRenderer.hpp"
#include "Camera.hpp"
#include "GBufferSwapchain.hpp"
#include "engine/rendering/renderpass/RenderPass.hpp"
namespace fgl::engine
{
class GBufferSwapchain;
void GBufferRenderer::setViewport( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent )
void GBufferRenderer::setViewport( const CommandBuffer& command_buffer, const vk::Extent2D extent )
{
vk::Viewport viewport {};
viewport.x = 0.0f;
@@ -24,32 +25,32 @@ namespace fgl::engine
const std::vector< vk::Viewport > viewports { viewport };
command_buffer.setViewport( 0, viewports );
command_buffer->setViewport( 0, viewports );
}
void GBufferRenderer::setScissor( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent )
void GBufferRenderer::setScissor( const CommandBuffer& command_buffer, const vk::Extent2D extent )
{
const vk::Rect2D scissor { { 0, 0 }, extent };
const std::vector< vk::Rect2D > scissors { scissor };
command_buffer.setScissor( 0, scissors );
command_buffer->setScissor( 0, scissors );
}
void GBufferRenderer::beginRenderPass(
const vk::raii::CommandBuffer& command_buffer, GBufferSwapchain& swapchain, const FrameIndex index )
void GBufferRenderer::
beginRenderPass( const CommandBuffer& command_buffer, GBufferSwapchain& swapchain, const FrameIndex index )
{
const vk::RenderingInfo info { swapchain.getRenderingInfo( index ) };
command_buffer.beginRendering( info );
command_buffer->beginRendering( info );
setViewport( command_buffer, swapchain.getExtent() );
setScissor( command_buffer, swapchain.getExtent() );
}
void GBufferRenderer::endRenderPass( const vk::raii::CommandBuffer& command_buffer )
void GBufferRenderer::endRenderPass( const CommandBuffer& command_buffer )
{
command_buffer.endRendering();
command_buffer->endRendering();
}
void GBufferRenderer::pass( FrameInfo& frame_info, GBufferSwapchain& camera_swapchain )
@@ -57,7 +58,7 @@ namespace fgl::engine
ZoneScopedN( "CameraRenderer::pass" );
m_culling_system.startPass( frame_info );
auto& command_buffer { frame_info.command_buffer };
auto& command_buffer { frame_info.command_buffer.render_cb };
camera_swapchain.transitionImages( command_buffer, GBufferSwapchain::INITAL, frame_info.frame_idx );

View File

@@ -5,7 +5,6 @@
#pragma once
#include "GBufferCompositor.hpp"
#include "GBufferSwapchain.hpp"
#include "engine/systems/prerender/CullingSystem.hpp"
#include "engine/systems/render/EntityRendererSystem.hpp"
#include "engine/systems/render/LineDrawer.hpp"
@@ -17,8 +16,8 @@ namespace fgl::engine
{
GBufferCompositor m_compositor;
void setViewport( const vk::raii::CommandBuffer& command_buffer, vk::Extent2D extent );
void setScissor( const vk::raii::CommandBuffer& command_buffer, vk::Extent2D extent );
void setViewport( const CommandBuffer& command_buffer, vk::Extent2D extent );
void setScissor( const CommandBuffer& command_buffer, vk::Extent2D extent );
CullingSystem m_culling_system {};
@@ -30,10 +29,9 @@ namespace fgl::engine
// SubPass 1
// CompositionSystem m_composition_system {};
void beginRenderPass(
const vk::raii::CommandBuffer& command_buffer, GBufferSwapchain& swapchain, FrameIndex index );
void beginRenderPass( const CommandBuffer& command_buffer, GBufferSwapchain& swapchain, FrameIndex index );
void endRenderPass( const vk::raii::CommandBuffer& command_buffer );
void endRenderPass( const CommandBuffer& command_buffer );
public:

View File

@@ -12,9 +12,9 @@ namespace fgl::engine
std::vector< std::unique_ptr< descriptors::DescriptorSet > > GBufferSwapchain::createGBufferDescriptors()
{
std::vector< std::unique_ptr< descriptors::DescriptorSet > > data {};
data.resize( PresentSwapChain::MAX_FRAMES_IN_FLIGHT );
data.resize( constants::MAX_FRAMES_IN_FLIGHT );
for ( PresentIndex i = 0; i < PresentSwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
for ( PresentIndex i = 0; i < constants::MAX_FRAMES_IN_FLIGHT; ++i )
{
//auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) };
auto set { gbuffer_set.create() };
@@ -37,8 +37,8 @@ namespace fgl::engine
return data;
}
void GBufferSwapchain::transitionImages(
vk::raii::CommandBuffer& command_buffer, const std::uint16_t stage_id, const FrameIndex index )
void GBufferSwapchain::
transitionImages( CommandBuffer& command_buffer, const std::uint16_t stage_id, const FrameIndex index )
{
switch ( stage_id )
{
@@ -63,7 +63,7 @@ namespace fgl::engine
vk::ImageAspectFlagBits::eDepth ),
};
command_buffer.pipelineBarrier(
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eTopOfPipe,
vk::PipelineStageFlagBits::eColorAttachmentOutput
| vk::PipelineStageFlagBits::eEarlyFragmentTests
@@ -96,7 +96,7 @@ namespace fgl::engine
// vk::ImageAspectFlagBits::eDepth ),
};
command_buffer.pipelineBarrier(
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::PipelineStageFlagBits::eFragmentShader,
vk::DependencyFlags( 0 ),
@@ -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 { PresentSwapChain::MAX_FRAMES_IN_FLIGHT };
constexpr auto image_count { constants::MAX_FRAMES_IN_FLIGHT };
m_gbuffer.m_color.createResources( image_count, m_extent );
m_gbuffer.m_position.createResources( image_count, m_extent );

View File

@@ -53,7 +53,7 @@ namespace fgl::engine
FINAL
};
void transitionImages( vk::raii::CommandBuffer& command_buffer, std::uint16_t stage_id, FrameIndex index );
void transitionImages( CommandBuffer& command_buffer, std::uint16_t stage_id, FrameIndex index );
vk::RenderingInfo getRenderingInfo( const FrameIndex frame_index );
GBufferSwapchain( vk::Extent2D extent );

View File

@@ -49,4 +49,6 @@ namespace fgl::engine::constants
constexpr TextureID INVALID_TEXTURE_ID { 0 };
constexpr std::uint8_t MAX_FRAMES_IN_FLIGHT { 2 };
} // namespace fgl::engine::constants

View File

@@ -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 > PresentSwapChain::MAX_FRAMES_IN_FLIGHT + 1 )
if ( counter > constants::MAX_FRAMES_IN_FLIGHT + 1 )
{
itter = QUEUE.erase( itter );
}

View File

@@ -0,0 +1,25 @@
//
// Created by kj16609 on 2/14/25.
//
#include "CommandBuffer.hpp"
#include "CommandBufferPool.hpp"
#include "debug/logging/logging.hpp"
namespace fgl::engine
{
CommandBufferHandle::CommandBufferHandle( vk::raii::CommandBuffer&& buffer, const CommandType type ) :
m_cmd_buffer( std::move( buffer ) ),
m_type( type )
{}
CommandBufferHandle::~CommandBufferHandle()
{
log::warn( "Command buffer handle destroyed!" );
}
vk::raii::CommandBuffer& CommandBufferHandle::cmd()
{
return m_cmd_buffer;
}
} // namespace fgl::engine

View File

@@ -0,0 +1,53 @@
//
// Created by kj16609 on 2/14/25.
//
#pragma once
#include <vulkan/vulkan_raii.hpp>
#include "FGL_DEFINES.hpp"
namespace fgl::engine
{
class CommandBufferPool;
/**
* @brief Contains a vk::raii::CommandBuffer to be used for recording, and a list of all assets to be appended too for each asset used.
*/
class CommandBufferHandle
{
public:
enum CommandType : std::uint8_t
{
Invalid = 0,
Primary = 1,
Secondary = 2
} m_type;
private:
/*
* Later on we'll want to append to this list in order to keep various assets alive
* that need to persist for this command buffer. Once this command buffer is reset,
* we can then drop all the assets kept in this list if they are ready to be deleted
*/
// std::vector< std::shared_ptr< AssetHandle > > m_asset_handles {};
vk::raii::CommandBuffer m_cmd_buffer;
friend class CommandBufferPool;
explicit CommandBufferHandle( vk::raii::CommandBuffer&& buffer, CommandType type );
public:
FGL_DELETE_COPY( CommandBufferHandle );
FGL_DELETE_MOVE( CommandBufferHandle );
CommandBufferHandle() = delete;
~CommandBufferHandle();
vk::raii::CommandBuffer& cmd();
};
} // namespace fgl::engine

View File

@@ -0,0 +1,199 @@
//
// Created by kj16609 on 2/14/25.
//
#include "CommandBufferPool.hpp"
#include "devices/Device.hpp"
namespace fgl::engine
{
/*
std::shared_ptr< CommandBufferHandle > CommandBufferPool::createBuffer()
{
CommandBufferHandle* handle_ptr { nullptr };
vk::CommandBufferAllocateInfo allocate_info {};
allocate_info.commandBufferCount = 1;
return std::shared_ptr< CommandBufferHandle >( handle_ptr );
}
*/
// No longer need eTransient as these will persist from start until destruction of the engine.
// eResetCommandBuffer indicates that we'll be the ones resetting the command buffer.
constexpr vk::CommandPoolCreateFlags CREATE_FLAGS { vk::CommandPoolCreateFlagBits::eResetCommandBuffer };
CommandBuffer::CommandBuffer( std::shared_ptr< CommandBufferHandle >&& handle, CommandBufferPool* pool ) :
m_handle( std::move( handle ) ),
m_pool( pool )
{}
vk::raii::CommandBuffer* CommandBuffer::operator->() const
{
return &m_handle->cmd();
}
vk::raii::CommandBuffer& CommandBuffer::operator*() const
{
return m_handle->cmd();
}
void CommandBuffer::setName( const char* name )
{
vk::DebugUtilsObjectNameInfoEXT info {};
info.setObjectType( vk::ObjectType::eCommandBuffer );
info.setPObjectName( name );
info.setObjectHandle(
reinterpret_cast< std::uint64_t >( static_cast< VkCommandBuffer >( *( m_handle->cmd() ) ) ) );
Device::getInstance().setDebugUtilsObjectName( info );
}
CommandBuffer::CommandBuffer( CommandBuffer&& other ) noexcept :
m_handle( std::move( other.m_handle ) ),
m_pool( other.m_pool )
{
FGL_ASSERT( m_handle, "Invalid handle when moving" );
other.m_handle = nullptr;
other.m_pool = nullptr;
}
CommandBuffer::~CommandBuffer()
{
if ( m_handle ) m_pool->markInFlight( std::move( m_handle ) );
}
void CommandBufferPool::advanceInFlight()
{
std::lock_guard guard { m_queue_mtx };
in_flight_idx += 1;
if ( in_flight_idx >= constants::MAX_FRAMES_IN_FLIGHT ) in_flight_idx = 0;
std::vector< std::shared_ptr< CommandBufferHandle > >& vec { m_in_flight[ in_flight_idx ] };
// return all command buffers back to the pool to prepare for new insertions
for ( std::shared_ptr< CommandBufferHandle >& buffer : vec )
{
// Reset command buffer before returning it back to the pool
buffer->cmd().reset();
FGL_ASSERT( buffer->m_type != CommandBufferHandle::Invalid, "Command buffer type invalid" );
auto& target { buffer->m_type == CommandBufferHandle::Primary ? m_available_p_buffers :
m_available_s_buffers };
target.push( std::move( buffer ) );
}
vec.clear();
}
void CommandBufferPool::markInFlight( std::shared_ptr< CommandBufferHandle >&& buffer )
{
FGL_ASSERT( buffer, "Buffer was not valid!" );
m_in_flight[ in_flight_idx ].emplace_back( std::move( buffer ) );
}
CommandBufferPool createGraphicsPool( vk::raii::Device& device, PhysicalDevice& physical_device )
{
const auto graphics_index { physical_device.queueInfo().getIndex( vk::QueueFlagBits::eGraphics ) };
return { device, graphics_index };
}
CommandBufferPool createTransferPool( vk::raii::Device& device, PhysicalDevice& physical_device )
{
const auto transfer_index { physical_device.queueInfo().getIndex( vk::QueueFlagBits::eTransfer ) };
return { device, transfer_index };
}
CommandBufferPool::CommandBufferPool( vk::raii::Device& device, const std::uint32_t queue_index ) :
m_pool_info( CREATE_FLAGS, queue_index ),
m_pool( device.createCommandPool( m_pool_info ) ),
in_flight_idx( 0 )
{
constexpr std::size_t command_buffer_target { 8 };
constexpr std::size_t secondary_multip { 16 };
vk::CommandBufferAllocateInfo info {};
info.setCommandPool( m_pool );
{
info.setCommandBufferCount( command_buffer_target );
info.setLevel( vk::CommandBufferLevel::ePrimary );
std::vector< vk::raii::CommandBuffer > command_buffers { device.allocateCommandBuffers( info ) };
std::lock_guard guard { m_queue_mtx };
for ( auto& command_buffer : command_buffers )
{
auto* ptr { new CommandBufferHandle( std::move( command_buffer ), CommandBufferHandle::Primary ) };
m_available_p_buffers.push( std::shared_ptr< CommandBufferHandle >( ptr ) );
}
}
{
info.setLevel( vk::CommandBufferLevel::eSecondary );
info.setCommandBufferCount( command_buffer_target * secondary_multip );
std::vector< vk::raii::CommandBuffer > command_buffers { device.allocateCommandBuffers( info ) };
std::lock_guard guard { m_queue_mtx };
for ( auto& command_buffer : command_buffers )
{
auto* ptr { new CommandBufferHandle( std::move( command_buffer ), CommandBufferHandle::Secondary ) };
m_available_s_buffers.push( std::shared_ptr< CommandBufferHandle >( ptr ) );
}
}
}
CommandBufferPool::~CommandBufferPool()
{}
[[nodiscard]] CommandBuffer CommandBufferPool::getCommandBuffer( const CommandBufferHandle::CommandType type )
{
std::lock_guard guard { m_queue_mtx };
auto& source { type == CommandBufferHandle::Primary ? m_available_p_buffers : m_available_s_buffers };
FGL_ASSERT( source.size() > 0, "No available command buffers!" );
auto buffer = source.front();
source.pop();
return { std::move( buffer ), this };
}
std::vector< CommandBuffer > CommandBufferPool::
getCommandBuffers( const std::size_t count, const CommandBufferHandle::CommandType type )
{
std::lock_guard guard { m_queue_mtx };
std::vector< CommandBuffer > command_buffers {};
command_buffers.reserve( count );
auto& source { type == CommandBufferHandle::Primary ? m_available_p_buffers : m_available_s_buffers };
for ( std::size_t i = 0; i < count; ++i )
{
FGL_ASSERT( source.size() > 0, "No available command buffers!" );
CommandBuffer buffer { std::move( source.front() ), this };
command_buffers.emplace_back( std::move( buffer ) );
source.pop();
}
return command_buffers;
}
} // namespace fgl::engine

View File

@@ -0,0 +1,89 @@
//
// Created by kj16609 on 2/14/25.
//
#pragma once
#include <memory>
#include <queue>
#include "CommandBuffer.hpp"
#include "FGL_DEFINES.hpp"
#include "constants.hpp"
#include "devices/PhysicalDevice.hpp"
#include "types.hpp"
namespace fgl::engine
{
class Device;
class CommandBuffer
{
std::shared_ptr< CommandBufferHandle > m_handle;
CommandBufferPool* m_pool;
CommandBuffer( std::shared_ptr< CommandBufferHandle >&& handle, CommandBufferPool* pool );
friend class CommandBufferPool;
public:
vk::raii::CommandBuffer* operator->() const;
vk::raii::CommandBuffer& operator*() const;
void setName( const char* name );
FGL_DELETE_COPY( CommandBuffer );
FGL_DELETE_MOVE_ASSIGN( CommandBuffer );
CommandBuffer( CommandBuffer&& other ) noexcept;
~CommandBuffer();
};
class CommandBufferPool
{
vk::CommandPoolCreateInfo m_pool_info;
vk::raii::CommandPool m_pool;
std::mutex m_queue_mtx {};
//! Available primary command buffers
std::queue< std::shared_ptr< CommandBufferHandle > > m_available_s_buffers {};
//! Available secondary command buffers
std::queue< std::shared_ptr< CommandBufferHandle > > m_available_p_buffers {};
// std::shared_ptr< CommandBufferHandle > createBuffer();
//! Command pools that might still be in flight.
FrameIndex in_flight_idx;
std::array< std::vector< std::shared_ptr< CommandBufferHandle > >, constants::MAX_FRAMES_IN_FLIGHT >
m_in_flight {};
void markInFlight( std::shared_ptr< CommandBufferHandle >&& buffer );
friend class CommandBuffer;
public:
CommandBufferPool() = delete;
CommandBufferPool( vk::raii::Device& device, std::uint32_t queue_index );
// CommandBufferPool( PhysicalDevice& phy_device, vk::raii::Device& device );
~CommandBufferPool();
FGL_DELETE_COPY( CommandBufferPool );
FGL_DELETE_MOVE( CommandBufferPool );
//! Gets an available and empty command buffer
//TODO: According to vulkan it's recomended to have a entire command pool per thread,
// However because we are going to re-use as many of these buffers, I'm unsure if it's needed?
CommandBuffer getCommandBuffer( CommandBufferHandle::CommandType type );
std::vector< CommandBuffer > getCommandBuffers( std::size_t count, CommandBufferHandle::CommandType type );
//! Moves the in-flight tracking number to the next index
void advanceInFlight();
};
CommandBufferPool createGraphicsPool( vk::raii::Device& device, PhysicalDevice& physical_device );
CommandBufferPool createTransferPool( vk::raii::Device& device, PhysicalDevice& physical_device );
} // namespace fgl::engine

View File

@@ -0,0 +1,21 @@
//
// Created by kj16609 on 2/14/25.
//
#include "CommandBuffers.hpp"
namespace fgl::engine
{
CommandBuffers::CommandBuffers( std::vector< CommandBuffer >&& buffers ) :
imgui_cb( std::move( buffers[ 0 ] ) ),
transfer_cb( std::move( buffers[ 1 ] ) ),
render_cb( std::move( buffers[ 2 ] ) ),
composition_cb( std::move( buffers[ 3 ] ) )
{
imgui_cb.setName( "ImGui CB" );
transfer_cb.setName( "Transfer CB" );
render_cb.setName( "Render CB" );
composition_cb.setName( "Composition CB" );
}
} // namespace fgl::engine

View File

@@ -0,0 +1,24 @@
//
// Created by kj16609 on 2/14/25.
//
#pragma once
#include <vulkan/vulkan_raii.hpp>
#include "CommandBufferPool.hpp"
namespace fgl::engine
{
struct CommandBuffers
{
CommandBuffer imgui_cb;
CommandBuffer transfer_cb;
CommandBuffer render_cb;
CommandBuffer composition_cb;
CommandBuffers() = delete;
CommandBuffers( std::vector< CommandBuffer >&& buffers );
};
} // namespace fgl::engine

View File

@@ -117,8 +117,7 @@ namespace fgl::engine
return result;
}
vk::Result PresentSwapChain::
submitCommandBuffers( const vk::raii::CommandBuffer& buffers, const PresentIndex present_index )
vk::Result PresentSwapChain::submitCommandBuffers( const CommandBuffer& buffers, const PresentIndex present_index )
{
ZoneScoped;
@@ -142,7 +141,7 @@ namespace fgl::engine
m_submit_info.setWaitDstStageMask( wait_stages );
m_submit_info.commandBufferCount = 1;
m_submit_info.pCommandBuffers = &( *buffers );
m_submit_info.pCommandBuffers = &( **buffers );
std::vector< vk::Semaphore > signaled_semaphores { m_render_finished_sem[ m_current_frame_index ] };
m_submit_info.setSignalSemaphores( signaled_semaphores );
@@ -171,14 +170,14 @@ namespace fgl::engine
throw std::runtime_error( "failed to present swap chain image!" );
}
m_current_frame_index = static_cast<
FrameIndex >( ( m_current_frame_index + static_cast< FrameIndex >( 1 ) ) % MAX_FRAMES_IN_FLIGHT );
m_current_frame_index = static_cast< FrameIndex >(
( m_current_frame_index + static_cast< FrameIndex >( 1 ) ) % constants::MAX_FRAMES_IN_FLIGHT );
return vk::Result::eSuccess;
}
void PresentSwapChain::
transitionImages( const vk::raii::CommandBuffer& command_buffer, StageID stage_id, FrameIndex frame_index )
transitionImages( const CommandBuffer& command_buffer, const StageID stage_id, const FrameIndex frame_index )
{
switch ( stage_id )
{
@@ -196,7 +195,7 @@ namespace fgl::engine
vk::ImageAspectFlagBits::eDepth )
};
command_buffer.pipelineBarrier(
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eTopOfPipe,
vk::PipelineStageFlagBits::eColorAttachmentOutput
| vk::PipelineStageFlagBits::eEarlyFragmentTests
@@ -216,7 +215,7 @@ namespace fgl::engine
vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::ePresentSrcKHR ),
};
command_buffer.pipelineBarrier(
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::PipelineStageFlagBits::eBottomOfPipe,
vk::DependencyFlags( 0 ),
@@ -315,7 +314,7 @@ namespace fgl::engine
vk::FenceCreateInfo fenceInfo {};
fenceInfo.flags = vk::FenceCreateFlagBits::eSignaled;
for ( size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++ )
for ( size_t i = 0; i < constants::MAX_FRAMES_IN_FLIGHT; i++ )
{
auto& device { Device::getInstance() };

View File

@@ -15,8 +15,6 @@ namespace fgl::engine
{
public:
static constexpr FrameIndex MAX_FRAMES_IN_FLIGHT { 2 };
enum StageID
{
INITAL,
@@ -105,12 +103,12 @@ namespace fgl::engine
[[nodiscard]] std::pair< vk::Result, PresentIndex > acquireNextImage();
[[nodiscard]] vk::Result
submitCommandBuffers( const vk::raii::CommandBuffer& buffers, PresentIndex present_index );
submitCommandBuffers( const CommandBuffer& buffers, PresentIndex present_index );
void transitionImages( const vk::raii::CommandBuffer& command_buffer, StageID inital, FrameIndex frame_index );
void transitionImages( const CommandBuffer& command_buffer, StageID stage_id, FrameIndex frame_index );
};
template < typename T >
using PerFrameArray = std::array< T, PresentSwapChain::MAX_FRAMES_IN_FLIGHT >;
using PerFrameArray = std::array< T, constants::MAX_FRAMES_IN_FLIGHT >;
} // namespace fgl::engine

View File

@@ -122,11 +122,11 @@ namespace fgl::engine
alloc_info.pNext = VK_NULL_HANDLE;
alloc_info.commandPool = Device::getInstance().getCommandPool();
alloc_info.level = vk::CommandBufferLevel::ePrimary;
alloc_info.commandBufferCount = PresentSwapChain::MAX_FRAMES_IN_FLIGHT;
alloc_info.commandBufferCount = constants::MAX_FRAMES_IN_FLIGHT;
m_command_buffer = Device::getInstance().device().allocateCommandBuffers( alloc_info );
m_tracy_ctx = createContext( m_phy_device, Device::getInstance(), m_command_buffer[ 0 ] );
//TODO: Restore tracy functionality, It's wanting a command buffer.
//TODO: Figure out if the command buffer it wants is just for setup or needs to be ran occasionally
// m_tracy_ctx = createContext( m_phy_device, Device::getInstance(), m_command_buffer[ 0 ] );
/*
m_tracy_ctx = TracyVkContextCalibrated(
@@ -139,8 +139,6 @@ namespace fgl::engine
*/
alloc_info.level = vk::CommandBufferLevel::eSecondary;
m_gui_command_buffer = Device::getInstance()->allocateCommandBuffers( alloc_info );
}
void Renderer::recreateSwapchain()
@@ -169,7 +167,7 @@ namespace fgl::engine
}
}
vk::raii::CommandBuffer& Renderer::beginFrame()
std::optional< CommandBuffers > Renderer::beginFrame()
{
assert( !is_frame_started && "Cannot begin frame while frame is already in progress" );
auto [ result, present_index ] = m_swapchain->acquireNextImage();
@@ -184,28 +182,60 @@ namespace fgl::engine
throw std::runtime_error( "Failed to acquire swap chain image" );
is_frame_started = true;
auto& command_buffer { getCurrentCommandbuffer() };
vk::CommandBufferBeginInfo begin_info {};
begin_info.pNext = VK_NULL_HANDLE;
//begin_info.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit;
begin_info.pInheritanceInfo = VK_NULL_HANDLE;
auto command_buffers {
Device::getInstance().getCmdBufferPool().getCommandBuffers( 4, CommandBufferHandle::Secondary )
};
command_buffer.begin( begin_info );
vk::CommandBufferBeginInfo info {};
info.pNext = VK_NULL_HANDLE;
return command_buffer;
vk::CommandBufferInheritanceInfo inheritance_info {};
inheritance_info.framebuffer = VK_NULL_HANDLE;
inheritance_info.renderPass = VK_NULL_HANDLE;
inheritance_info.subpass = 0;
info.pInheritanceInfo = &inheritance_info;
for ( auto& command_buffer : command_buffers )
{
command_buffer->begin( info );
}
CommandBuffers buffers { std::move( command_buffers ) };
return buffers;
}
void Renderer::endFrame()
void Renderer::endFrame( CommandBuffers& buffers )
{
ZoneScopedN( "Ending frame" );
assert( is_frame_started && "Cannot call end frame while frame is not in progress" );
auto& command_buffer { getCurrentCommandbuffer() };
// auto& command_buffer { getCurrentCommandbuffer() };
command_buffer.end();
// Get a primary command buffer
const auto primary_cmd {
Device::getInstance().getCmdBufferPool().getCommandBuffer( CommandBufferHandle::Primary )
};
const auto result { m_swapchain->submitCommandBuffers( command_buffer, current_present_index ) };
vk::CommandBufferBeginInfo begin_info {};
begin_info.pNext = VK_NULL_HANDLE;
begin_info.pInheritanceInfo = VK_NULL_HANDLE;
primary_cmd->begin( begin_info );
buffers.transfer_cb->end();
buffers.render_cb->end();
buffers.composition_cb->end();
buffers.imgui_cb->end();
// run all secondary command buffers
primary_cmd->executeCommands(
{ *buffers.transfer_cb, *buffers.render_cb, *buffers.composition_cb, *buffers.imgui_cb } );
primary_cmd->end();
const auto result { m_swapchain->submitCommandBuffers( primary_cmd, current_present_index ) };
if ( result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR
|| m_window.wasWindowResized() )
@@ -217,11 +247,10 @@ 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 ) % PresentSwapChain::MAX_FRAMES_IN_FLIGHT );
current_frame_idx = static_cast< std::uint16_t >( ( current_frame_idx + 1 ) % constants::MAX_FRAMES_IN_FLIGHT );
}
void Renderer::setViewport( const vk::raii::CommandBuffer& buffer )
void Renderer::setViewport( const CommandBuffer& buffer )
{
vk::Viewport viewport {};
viewport.x = 0.0f;
@@ -233,19 +262,19 @@ namespace fgl::engine
const std::vector< vk::Viewport > viewports { viewport };
buffer.setViewport( 0, viewports );
buffer->setViewport( 0, viewports );
}
void Renderer::setScissor( const vk::raii::CommandBuffer& buffer )
void Renderer::setScissor( const CommandBuffer& buffer )
{
const vk::Rect2D scissor { { 0, 0 }, m_swapchain->getSwapChainExtent() };
const std::vector< vk::Rect2D > scissors { scissor };
buffer.setScissor( 0, scissors );
buffer->setScissor( 0, scissors );
}
void Renderer::beginSwapchainRendererPass( vk::raii::CommandBuffer& buffer )
void Renderer::beginSwapchainRendererPass( CommandBuffer& buffer )
{
assert( is_frame_started && "Cannot call beginSwapChainRenderPass if frame is not in progress" );
@@ -253,17 +282,17 @@ namespace fgl::engine
m_swapchain->transitionImages( buffer, PresentSwapChain::INITAL, current_present_index );
buffer.beginRendering( info );
buffer->beginRendering( info );
setViewport( buffer );
setScissor( buffer );
}
void Renderer::endSwapchainRendererPass( vk::raii::CommandBuffer& buffer )
void Renderer::endSwapchainRendererPass( CommandBuffer& buffer )
{
assert( is_frame_started && "Cannot call endSwapChainRenderPass if frame is not in progress" );
buffer.endRendering();
buffer->endRendering();
m_swapchain->transitionImages( buffer, PresentSwapChain::FINAL, current_present_index );
}

View File

@@ -4,18 +4,17 @@
#pragma once
// clang-format off
#include <vulkan/vulkan.hpp>
#include <tracy/TracyVulkan.hpp>
// clang-format on
#include <cassert>
#include <memory>
#include "CommandBuffers.hpp"
#include "PresentSwapChain.hpp"
//clang-format: off
#include <tracy/TracyVulkan.hpp>
//clang-format: on
namespace fgl::engine
{
@@ -25,9 +24,6 @@ namespace fgl::engine
PhysicalDevice& m_phy_device;
std::unique_ptr< PresentSwapChain > m_swapchain;
std::vector< vk::raii::CommandBuffer > m_command_buffer {};
std::vector< vk::raii::CommandBuffer > m_gui_command_buffer {};
TracyVkCtx m_tracy_ctx { nullptr };
PresentIndex current_present_index { std::numeric_limits< PresentIndex >::max() };
@@ -53,26 +49,20 @@ namespace fgl::engine
bool isFrameInProgress() const { return is_frame_started; }
vk::raii::CommandBuffer& getCurrentCommandbuffer()
{
assert( is_frame_started && "Cannot get command buffer while frame not in progress" );
return m_command_buffer[ current_frame_idx ];
}
vk::raii::CommandBuffer& getCurrentGuiCommandBuffer() { return m_gui_command_buffer[ current_frame_idx ]; }
TracyVkCtx getCurrentTracyCTX() const { return m_tracy_ctx; }
float getAspectRatio() const { return m_swapchain->extentAspectRatio(); }
vk::raii::CommandBuffer& beginFrame();
void endFrame();
// vk::raii::CommandBuffer& beginFrame();
std::optional< CommandBuffers > beginFrame();
void setViewport( const vk::raii::CommandBuffer& buffer );
void setScissor( const vk::raii::CommandBuffer& buffer );
void endFrame( CommandBuffers& buffers );
void beginSwapchainRendererPass( vk::raii::CommandBuffer& buffer );
void endSwapchainRendererPass( vk::raii::CommandBuffer& buffer );
void setViewport( const CommandBuffer& buffer );
void setScissor( const CommandBuffer& buffer );
void beginSwapchainRendererPass( CommandBuffer& buffer );
void endSwapchainRendererPass( CommandBuffer& buffer );
PresentSwapChain& getSwapChain() { return *m_swapchain; }

View File

@@ -167,6 +167,7 @@ namespace fgl::engine
m_physical_device( m_instance, m_surface_khr ),
device_creation_info( m_physical_device ),
m_device( m_physical_device, device_creation_info.m_create_info ),
m_command_pool( createGraphicsPool( m_device, m_physical_device ) ),
m_commandPool( m_device.createCommandPool( commandPoolInfo() ) ),
m_graphics_queue( m_device
.getQueue( m_physical_device.queueInfo().getIndex( vk::QueueFlagBits::eGraphics ), 0 ) ),

View File

@@ -10,6 +10,7 @@
#include "engine/rendering/Instance.hpp"
#include "engine/rendering/Surface.hpp"
#include "extensions.hpp"
#include "rendering/CommandBufferPool.hpp"
#include "vma/vma_impl.hpp"
namespace fgl::engine
@@ -89,6 +90,8 @@ namespace fgl::engine
vk::raii::Device m_device;
CommandBufferPool m_command_pool;
vk::raii::CommandPool m_commandPool;
vk::raii::Queue m_graphics_queue;
@@ -101,6 +104,7 @@ namespace fgl::engine
vk::PhysicalDeviceProperties m_properties;
vk::CommandPoolCreateInfo commandPoolInfo();
CommandBufferPool& getCmdBufferPool() { return m_command_pool; }
Device( Window&, Instance& );
~Device();

View File

@@ -26,7 +26,7 @@ namespace fgl::engine
m_builder_state( std::forward< std::unique_ptr< PipelineBuilder::BuilderState > >( builder_state ) )
{}
void Pipeline::bind( vk::raii::CommandBuffer& cmd_buffer )
void Pipeline::bind( CommandBuffer& cmd_buffer )
{
if ( flags::shouldReloadShaders() )
{
@@ -40,21 +40,21 @@ namespace fgl::engine
}
}
cmd_buffer.bindPipeline( vk::PipelineBindPoint::eGraphics, m_pipeline );
cmd_buffer->bindPipeline( vk::PipelineBindPoint::eGraphics, m_pipeline );
}
void Pipeline::bindDescriptor(
vk::raii::CommandBuffer& command_buffer,
CommandBuffer& command_buffer,
const descriptors::DescriptorIDX descriptor_idx,
descriptors::DescriptorSet& set )
{
const std::vector< vk::DescriptorSet > sets { *set };
constexpr std::vector< std::uint32_t > offsets {};
command_buffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, m_layout, descriptor_idx, sets, offsets );
command_buffer->bindDescriptorSets( vk::PipelineBindPoint::eGraphics, m_layout, descriptor_idx, sets, offsets );
}
void Pipeline::bindDescriptor( vk::raii::CommandBuffer& comd_buffer, descriptors::DescriptorSet& set )
void Pipeline::bindDescriptor( CommandBuffer& comd_buffer, descriptors::DescriptorSet& set )
{
bindDescriptor( comd_buffer, set.setIDX(), set );
}

View File

@@ -31,19 +31,19 @@ namespace fgl::engine
vk::raii::PipelineLayout&& layout,
std::unique_ptr< PipelineBuilder::BuilderState >&& builder_state );
void bind( vk::raii::CommandBuffer& );
void bind( CommandBuffer& cmd_buffer );
void bindDescriptor(
vk::raii::CommandBuffer&, descriptors::DescriptorIDX descriptor_idx, descriptors::DescriptorSet& set );
void bindDescriptor( vk::raii::CommandBuffer& comd_buffer, descriptors::DescriptorSet& set );
CommandBuffer&, descriptors::DescriptorIDX descriptor_idx, descriptors::DescriptorSet& set );
void bindDescriptor( CommandBuffer& comd_buffer, descriptors::DescriptorSet& set );
void setDebugName( const char* str );
template < typename T >
requires std::is_trivially_copyable_v< T >
void pushConstant( vk::raii::CommandBuffer& command_buffer, vk::ShaderStageFlags stage, const T& t )
void pushConstant( CommandBuffer& command_buffer, vk::ShaderStageFlags stage, const T& t )
{
command_buffer.pushConstants< T >( m_layout, stage, 0, { t } );
command_buffer->pushConstants< T >( m_layout, stage, 0, { t } );
}
};

View File

@@ -5,7 +5,6 @@
#include "GuiSystem.hpp"
#include "engine/FrameInfo.hpp"
#include "engine/assets/model/SimpleVertex.hpp"
#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp"
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp"
@@ -22,8 +21,10 @@ namespace fgl::engine
builder.addDescriptorSet( gui_descriptor_set );
builder.setAttributeDescriptions( SimpleVertex::getAttributeDescriptions() );
builder.setBindingDescriptions( SimpleVertex::getBindingDescriptions() );
// VUID-vkCmdDraw-None-04008: States that vertex binding 0 is null handle, and must be bound.
// Not entirely sure why we had added vertex bindings to this in the first place?
// builder.setAttributeDescriptions( SimpleVertex::getAttributeDescriptions() );
// builder.setBindingDescriptions( SimpleVertex::getBindingDescriptions() );
builder.setVertexShader( Shader::loadVertex( "shaders/gui-compose.slang" ) );
builder.setFragmentShader( Shader::loadFragment( "shaders/gui-compose.slang" ) );
@@ -34,9 +35,9 @@ namespace fgl::engine
m_pipeline->setDebugName( "Gui Pipeline" );
}
vk::raii::CommandBuffer& GuiSystem::setupSystem( FrameInfo& info )
CommandBuffer& GuiSystem::setupSystem( FrameInfo& info )
{
auto& command_buffer { info.command_buffer };
auto& command_buffer { info.command_buffer.imgui_cb };
m_pipeline->bind( command_buffer );
@@ -50,7 +51,7 @@ namespace fgl::engine
ZoneScopedN( "GuiSystem::pass" );
auto& command_buffer { setupSystem( info ) };
command_buffer.draw( 3, 1, 0, 0 );
command_buffer->draw( 3, 1, 0, 0 );
}
} // namespace fgl::engine

View File

@@ -20,7 +20,7 @@ namespace fgl::engine
std::unique_ptr< Pipeline > m_pipeline {};
//Setup isn't needed for this. So we can just never define this safely.
[[maybe_unused]] vk::raii::CommandBuffer& setupSystem( FrameInfo& info );
[[maybe_unused]] CommandBuffer& setupSystem( FrameInfo& info );
public:

View File

@@ -18,7 +18,7 @@
namespace fgl::engine
{
EntityRendererSystem::EntityRendererSystem( )
EntityRendererSystem::EntityRendererSystem()
{
ZoneScoped;
@@ -71,9 +71,9 @@ namespace fgl::engine
EntityRendererSystem::~EntityRendererSystem()
{}
vk::raii::CommandBuffer& EntityRendererSystem::setupSystem( const FrameInfo& info )
CommandBuffer& EntityRendererSystem::setupSystem( const FrameInfo& info )
{
auto& command_buffer { info.command_buffer };
auto& command_buffer { info.command_buffer.render_cb };
//This function becomes a dummy since we have multiple pipelines.
//We will instead bind the pipeline and descriptors for each stage of this pass.
@@ -144,7 +144,7 @@ namespace fgl::engine
void EntityRendererSystem::texturedPass( const FrameInfo& info )
{
ZoneScopedN( "Textured pass" );
auto& command_buffer { info.command_buffer };
auto& command_buffer { info.command_buffer.render_cb };
TracyVkZone( info.tracy_ctx, *command_buffer, "Render textured entities" );
auto [ draw_commands, model_matricies ] =
@@ -172,10 +172,10 @@ namespace fgl::engine
const std::vector< vk::Buffer > vert_buffers { info.model_vertex_buffer.getVkBuffer(),
model_matrix_info_buffer->getVkBuffer() };
command_buffer.bindVertexBuffers( 0, vert_buffers, { 0, model_matrix_info_buffer->getOffset() } );
command_buffer.bindIndexBuffer( info.model_index_buffer.getVkBuffer(), 0, vk::IndexType::eUint32 );
command_buffer->bindVertexBuffers( 0, vert_buffers, { 0, model_matrix_info_buffer->getOffset() } );
command_buffer->bindIndexBuffer( info.model_index_buffer.getVkBuffer(), 0, vk::IndexType::eUint32 );
command_buffer.drawIndexedIndirect(
command_buffer->drawIndexedIndirect(
draw_parameter_buffer->getVkBuffer(),
draw_parameter_buffer->getOffset(),
draw_parameter_buffer->size(),

View File

@@ -42,7 +42,7 @@ namespace fgl::engine
PerFrameArray< std::unique_ptr< DrawParameterBufferSuballocation > > m_draw_textured_parameter_buffers {};
PerFrameArray< std::unique_ptr< ModelMatrixInfoBufferSuballocation > > m_textured_model_matrix_info_buffers {};
vk::raii::CommandBuffer& setupSystem( const FrameInfo& );
CommandBuffer& setupSystem( const FrameInfo& );
public:

View File

@@ -24,7 +24,7 @@ namespace fgl::engine
inline static std::vector< VertexLine > m_lines {};
LineDrawer::LineDrawer( )
LineDrawer::LineDrawer()
{
PipelineBuilder builder { 0 };
@@ -48,9 +48,9 @@ namespace fgl::engine
LineDrawer::~LineDrawer()
{}
vk::raii::CommandBuffer& LineDrawer::setupSystem( FrameInfo& info )
CommandBuffer& LineDrawer::setupSystem( FrameInfo& info )
{
auto& command_buffer { info.command_buffer };
auto& command_buffer { info.command_buffer.render_cb };
m_pipeline->bind( command_buffer );
m_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() );
@@ -72,11 +72,11 @@ namespace fgl::engine
line_vertex_buffer = std::make_unique< HostVector< VertexLine > >( info.model_matrix_info_buffer, m_lines );
command_buffer.bindVertexBuffers( 0, line_vertex_buffer->getVkBuffer(), { line_vertex_buffer->getOffset() } );
command_buffer->bindVertexBuffers( 0, line_vertex_buffer->getVkBuffer(), { line_vertex_buffer->getOffset() } );
command_buffer.setLineWidth( 5.0f );
command_buffer->setLineWidth( 5.0f );
command_buffer.draw(
command_buffer->draw(
static_cast< std::uint32_t >( m_lines.size() * 2 ), static_cast< std::uint32_t >( m_lines.size() ), 0, 0 );
m_lines.clear();

View File

@@ -25,7 +25,7 @@ namespace fgl::engine
FGL_DELETE_COPY( LineDrawer );
FGL_DELETE_MOVE( LineDrawer );
vk::raii::CommandBuffer& setupSystem( FrameInfo& info );
CommandBuffer& setupSystem( FrameInfo& info );
void pass( FrameInfo& info );
LineDrawer();