Cleanup gui handling and destruction

This commit is contained in:
2025-01-21 23:59:00 -05:00
parent 89a0238c24
commit 9e3f9c2366
20 changed files with 366 additions and 274 deletions

View File

@@ -0,0 +1,131 @@
//
// Created by kj16609 on 1/21/25.
//
#include "EditorGuiContext.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
#include <backends/imgui_impl_glfw.h>
#include <backends/imgui_impl_vulkan.h>
#include <imgui_internal.h> // Included for DockBuilder since it's not exposed yet
#pragma GCC diagnostic pop
#include "FrameInfo.hpp"
#include "core.hpp"
#include "debug/timing/FlameGraph.hpp"
#include "descriptors/DescriptorPool.hpp"
#include "gui_window_names.hpp"
#include "rendering/RenderingFormats.hpp"
namespace fgl::editor
{
using namespace fgl::engine;
EditorGuiContext::EditorGuiContext( const Window& window )
{
ZoneScoped;
IMGUI_CHECKVERSION();
ImGui::CreateContext();
[[maybe_unused]] ImGuiIO& io { ImGui::GetIO() };
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
// io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
io.ConfigWindowsResizeFromEdges = true;
ImGui::StyleColorsDark();
Device& device { Device::getInstance() };
vk::PipelineRenderingCreateInfo pipeline_info {};
//TODO: Remove the ability for pickPresentFormat to be used here. Instead this should be hidden from the end user in roder to prevent shittery. This should be applied to everything else here too within reason.
const std::vector< vk::Format > color_formats { pickPresentFormat() };
pipeline_info.setColorAttachmentFormats( color_formats );
pipeline_info.setDepthAttachmentFormat( pickDepthFormat() );
ImGui_ImplGlfw_InitForVulkan( window.window(), true );
ImGui_ImplVulkan_InitInfo init_info {
.Instance = device.instance(),
.PhysicalDevice = *device.phyDevice().handle(),
.Device = *device,
.QueueFamily = device.phyDevice().queueInfo().getIndex( vk::QueueFlagBits::eGraphics ),
.Queue = *device.graphicsQueue(),
.DescriptorPool = *DescriptorPool::getInstance().getPool(),
.RenderPass = VK_NULL_HANDLE,
.MinImageCount = 2,
.ImageCount = 2,
.MSAASamples = VK_SAMPLE_COUNT_1_BIT,
.PipelineCache = VK_NULL_HANDLE,
.Subpass = 0,
.UseDynamicRendering = VK_TRUE,
.PipelineRenderingCreateInfo = pipeline_info,
.Allocator = VK_NULL_HANDLE,
.CheckVkResultFn = VK_NULL_HANDLE,
.MinAllocationSize = 1024 * 1024
};
ImGui_ImplVulkan_Init( &init_info );
}
EditorGuiContext::~EditorGuiContext()
{
ZoneScoped;
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void EditorGuiContext::beginDraw()
{
ZoneScoped;
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}
void EditorGuiContext::draw( FrameInfo& info )
{
ZoneScoped;
auto timer = debug::timing::push( "Draw ImGui" );
ImGui::ShowDemoWindow();
gui::drawDock();
gui::drawCameraOutputs( info );
gui::drawEntityGUI( info );
gui::drawEntityInfo( info );
ImGui::Begin( FILE_PICKER_NAME.data(), nullptr, ImGuiWindowFlags_MenuBar );
m_file_browser.drawGui( info );
ImGui::End();
gui::drawStats( info );
}
void EditorGuiContext::endDraw( vk::raii::CommandBuffer& command_buffer )
{
ZoneScoped;
ImGui::Render();
ImDrawData* data { ImGui::GetDrawData() };
ImGui_ImplVulkan_RenderDrawData( data, *command_buffer );
//ImGui::UpdatePlatformWindows();
//ImGui::RenderPlatformWindowsDefault();
}
void EditorGuiContext::endDraw( FrameInfo& info )
{
return endDraw( info.command_buffer );
}
} // namespace fgl::editor

View File

@@ -0,0 +1,23 @@
//
// Created by kj16609 on 1/21/25.
//
#pragma once
#include "FileBrowser.hpp"
namespace fgl::editor
{
class EditorGuiContext
{
engine::filesystem::FileBrowser m_file_browser {};
public:
EditorGuiContext( const engine::Window& window );
~EditorGuiContext();
void beginDraw();
void draw( engine::FrameInfo& info );
void endDraw( vk::raii::CommandBuffer& command_buffer );
void endDraw( engine::FrameInfo& info );
};
} // namespace fgl::editor

View File

@@ -18,41 +18,15 @@ namespace fgl::engine::filesystem
{
//! Textures for files (pre-rendered image, images, ect)
inline static std::unordered_map< std::filesystem::path, std::shared_ptr< Texture > > file_textures {};
inline static std::unique_ptr< DirInfo > current { nullptr };
constexpr std::uint32_t DESIRED_SIZE { 128 };
constexpr std::uint32_t PADDING { 2 };
inline static std::once_flag flag {};
inline static std::shared_ptr< Texture > folder_texture { nullptr };
inline static std::shared_ptr< Texture > file_texture { nullptr };
inline static std::shared_ptr< Texture > up_texture { nullptr };
constexpr std::uint32_t desired_size { 128 };
constexpr std::uint32_t padding { 2 };
const std::filesystem::path test_path { std::filesystem::current_path() / "assets" };
void prepareFileGUI()
{
//Prepare textures needed.
folder_texture = getTextureStore().load( "./assets/folder.png", vk::Format::eR8G8B8A8Unorm );
file_texture = getTextureStore().load( "./assets/file.png", vk::Format::eR8G8B8A8Unorm );
up_texture = getTextureStore().load( "./assets/up.png", vk::Format::eR8G8B8A8Unorm );
current = std::make_unique< DirInfo >( test_path );
}
void destroyFileGui()
{
folder_texture.reset();
file_texture.reset();
up_texture.reset();
file_textures.clear();
}
const std::filesystem::path TEST_PATH { std::filesystem::current_path() / "assets" };
void FileBrowser::drawGui( [[maybe_unused]] FrameInfo& info )
{
ZoneScoped;
std::call_once( flag, prepareFileGUI );
/*
if ( ImGui::BeginMenuBar() )
@@ -72,19 +46,20 @@ namespace fgl::engine::filesystem
}
*/
if ( !current )
if ( !m_current_dir )
{
log::critical( "Current has no value!" );
std::abort();
m_current_dir = std::make_unique< DirInfo >( std::filesystem::current_path() );
log::warn(
"Current directory was not set, Defaulting to current directory: {}", std::filesystem::current_path() );
}
auto size { ImGui::GetWindowSize() };
//TODO: Probably a cleaner way to do this.
size.x -= 12; // Remove scrollbar pixels
const float extra { std::fmod( size.x, static_cast< float >( desired_size + ( padding * 2 ) ) ) };
const float extra { std::fmod( size.x, static_cast< float >( DESIRED_SIZE + ( PADDING * 2 ) ) ) };
const auto cols {
static_cast< int >( ( size.x - extra ) / static_cast< float >( desired_size + ( padding * 2 ) ) )
static_cast< int >( ( size.x - extra ) / static_cast< float >( DESIRED_SIZE + ( PADDING * 2 ) ) )
};
if ( cols == 0 )
@@ -93,33 +68,33 @@ namespace fgl::engine::filesystem
return;
}
ImGui::PushStyleVar( ImGuiStyleVar_CellPadding, { padding, padding } );
ImGui::PushStyleVar( ImGuiStyleVar_CellPadding, { PADDING, PADDING } );
if ( current && ImGui::BeginTable( "Files", cols ) )
if ( m_current_dir && ImGui::BeginTable( "Files", cols ) )
{
for ( int i = 0; i < cols; ++i )
ImGui::TableSetupColumn( "", ImGuiTableColumnFlags_WidthFixed, desired_size );
ImGui::TableSetupColumn( "", ImGuiTableColumnFlags_WidthFixed, DESIRED_SIZE );
//List up if we can go up
if ( current->hasParent() )
if ( m_current_dir->hasParent() )
{
ImGui::TableNextColumn();
drawUp( current );
drawUp( m_current_dir );
}
assert( current );
assert( m_current_dir );
//List folders first
for ( std::size_t i = 0; i < current->folderCount(); ++i )
for ( std::size_t i = 0; i < m_current_dir->folderCount(); ++i )
{
ImGui::TableNextColumn();
drawFolder( current->dir( i ) );
drawFolder( m_current_dir->dir( i ) );
}
for ( std::size_t i = 0; i < current->fileCount(); ++i )
for ( std::size_t i = 0; i < m_current_dir->fileCount(); ++i )
{
ImGui::TableNextColumn();
drawFile( current->file( i ) );
drawFile( m_current_dir->file( i ) );
}
ImGui::EndTable();
@@ -148,22 +123,22 @@ namespace fgl::engine::filesystem
return format_ns::format( "{:0.2f} GB", static_cast< float >( size ) / 1000.0f / 1000.0f / 1000.0f );
}
void drawTexture( const FileInfo& info )
void FileBrowser::drawTexture( const FileInfo& info )
{
if ( auto itter = file_textures.find( info.path ); itter != file_textures.end() )
if ( auto itter = m_file_textures.find( info.path ); itter != m_file_textures.end() )
{
auto& [ path, texture ] = *itter;
texture->drawImGuiButton( { desired_size, desired_size } );
texture->drawImGuiButton( { DESIRED_SIZE, DESIRED_SIZE } );
}
else
{
file_texture->drawImGuiButton( { desired_size, desired_size } );
m_file_texture->drawImGuiButton( { DESIRED_SIZE, DESIRED_SIZE } );
auto tex { getTextureStore().load( info.path ) };
// Add the texture
file_textures.insert( std::make_pair( info.path, std::move( tex ) ) );
m_file_textures.insert( std::make_pair( info.path, std::move( tex ) ) );
}
if ( ImGui::BeginDragDropSource() )
@@ -176,15 +151,15 @@ namespace fgl::engine::filesystem
}
}
void drawBinary( [[maybe_unused]] const FileInfo& info )
void FileBrowser::drawBinary( [[maybe_unused]] const FileInfo& info )
{
// file_texture->drawImGui( { 128, 128 } );
file_texture->drawImGuiButton( { desired_size, desired_size } );
m_file_texture->drawImGuiButton( { DESIRED_SIZE, DESIRED_SIZE } );
//Unable to drag/drop because we have no idea what this is supposed to be for.
}
void drawModel( const FileInfo& info )
void FileBrowser::drawModel( const FileInfo& info )
{
//TODO: Pre-render preview image for models
drawBinary( info );
@@ -234,7 +209,7 @@ namespace fgl::engine::filesystem
{
ImGui::PushID( data.m_path.c_str() );
if ( folder_texture->drawImGuiButton( { desired_size, desired_size } ) )
if ( m_folder_texture->drawImGuiButton( { DESIRED_SIZE, DESIRED_SIZE } ) )
{
openFolder( data );
ImGui::PopID();
@@ -247,15 +222,22 @@ namespace fgl::engine::filesystem
ImGui::PopID();
}
FileBrowser::FileBrowser()
{
m_folder_texture = getTextureStore().load( "./assets/folder.png", vk::Format::eR8G8B8A8Unorm );
m_file_texture = getTextureStore().load( "./assets/file.png", vk::Format::eR8G8B8A8Unorm );
m_up_texture = getTextureStore().load( "./assets/up.png", vk::Format::eR8G8B8A8Unorm );
}
void FileBrowser::goUp()
{
current = current->up();
m_current_dir = m_current_dir->up();
}
void FileBrowser::openFolder( const DirInfo& dir )
{
file_textures.clear();
current = std::make_unique< DirInfo >( dir.m_path );
m_file_textures.clear();
m_current_dir = std::make_unique< DirInfo >( dir.m_path );
}
void FileBrowser::drawUp( const std::unique_ptr< DirInfo >& current_dir )
@@ -264,7 +246,7 @@ namespace fgl::engine::filesystem
ImGui::PushID( up->m_path.c_str() );
if ( up_texture->drawImGuiButton( { desired_size, desired_size } ) )
if ( m_up_texture->drawImGuiButton( { DESIRED_SIZE, DESIRED_SIZE } ) )
{
openFolder( *up );
}

View File

@@ -3,7 +3,11 @@
//
#pragma once
#include <mutex>
#include <unordered_map>
#include "../../../engine/filesystem/scanner/FileScanner.hpp"
#include "assets/texture/Texture.hpp"
namespace fgl::engine
{
@@ -16,14 +20,29 @@ namespace fgl::engine::filesystem
struct FileBrowser
{
static void goUp();
std::unordered_map< std::filesystem::path, std::shared_ptr< Texture > > m_file_textures {};
static void openFolder( const DirInfo& dir );
std::unique_ptr< DirInfo > m_current_dir { nullptr };
static void drawUp( const std::unique_ptr< DirInfo >& current_dir );
static void drawGui( FrameInfo& info );
static void drawFile( const FileInfo& data );
static void drawFolder( const DirInfo& data );
std::shared_ptr< Texture > m_folder_texture { nullptr };
std::shared_ptr< Texture > m_file_texture { nullptr };
std::shared_ptr< Texture > m_up_texture { nullptr };
FileBrowser();
void goUp();
void openFolder( const DirInfo& dir );
void drawUp( const std::unique_ptr< DirInfo >& current_dir );
void drawGui( FrameInfo& info );
void drawFile( const FileInfo& data );
void drawFolder( const DirInfo& data );
// drawers
void drawBinary( const FileInfo& info );
void drawModel( const FileInfo& info );
void drawTexture( const FileInfo& info );
};
void destroyFileGui();

View File

@@ -8,102 +8,21 @@
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
#include <backends/imgui_impl_glfw.h>
#include <backends/imgui_impl_vulkan.h>
#include <imgui_internal.h> // Included for DockBuilder since it's not exposed yet
#pragma GCC diagnostic pop
#include "FileBrowser.hpp"
#include "engine/assets/model/Model.hpp"
#include "engine/debug/DEBUG_NAMES.hpp"
#include "engine/debug/drawers.hpp"
#include "engine/debug/profiling/counters.hpp"
#include "engine/debug/timing/FlameGraph.hpp"
#include "engine/descriptors/DescriptorPool.hpp"
#include "engine/rendering/Renderer.hpp"
#include "engine/tree/octtree/OctTreeNode.hpp"
#include "gui_window_names.hpp"
#include "rendering/RenderingFormats.hpp"
#include "safe_include.hpp"
namespace fgl::engine::gui
{
void initGui( const Window& window, const Renderer& renderer )
{
ZoneScoped;
IMGUI_CHECKVERSION();
ImGui::CreateContext();
[[maybe_unused]] ImGuiIO& io { ImGui::GetIO() };
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
// io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
io.ConfigWindowsResizeFromEdges = true;
ImGui::StyleColorsDark();
Device& device { Device::getInstance() };
vk::PipelineRenderingCreateInfo pipeline_info {};
const std::vector< vk::Format > color_formats { pickPresentFormat() };
pipeline_info.setColorAttachmentFormats( color_formats );
pipeline_info.setDepthAttachmentFormat( pickDepthFormat() );
ImGui_ImplGlfw_InitForVulkan( window.window(), true );
ImGui_ImplVulkan_InitInfo init_info {
.Instance = device.instance(),
.PhysicalDevice = *device.phyDevice().handle(),
.Device = *device,
.QueueFamily = device.phyDevice().queueInfo().getIndex( vk::QueueFlagBits::eGraphics ),
.Queue = *device.graphicsQueue(),
.DescriptorPool = *DescriptorPool::getInstance().getPool(),
.RenderPass = VK_NULL_HANDLE,
.MinImageCount = 2,
.ImageCount = 2,
.MSAASamples = VK_SAMPLE_COUNT_1_BIT,
.PipelineCache = VK_NULL_HANDLE,
.Subpass = 0,
.UseDynamicRendering = VK_TRUE,
.PipelineRenderingCreateInfo = pipeline_info,
.Allocator = VK_NULL_HANDLE,
.CheckVkResultFn = VK_NULL_HANDLE,
.MinAllocationSize = 1024 * 1024
};
ImGui_ImplVulkan_Init( &init_info );
}
void beginImGui()
{
ZoneScoped;
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}
void endImGui( vk::raii::CommandBuffer& command_buffer )
{
ZoneScoped;
ImGui::Render();
ImDrawData* data { ImGui::GetDrawData() };
ImGui_ImplVulkan_RenderDrawData( data, *command_buffer );
//ImGui::UpdatePlatformWindows();
//ImGui::RenderPlatformWindowsDefault();
}
void endDrawImGui( FrameInfo& info )
{
endImGui( info.command_buffer );
}
inline void prepareDock( ImGuiID& primary_id )
{
ImGui::DockBuilderRemoveNode( primary_id );
@@ -177,29 +96,6 @@ namespace fgl::engine::gui
// ImGui::PopStyleVar();
}
void startDrawImGui( [[maybe_unused]] FrameInfo& info )
{
beginImGui();
profiling::resetCounters();
}
void drawImGui( FrameInfo& info )
{
ZoneScoped;
auto timer = debug::timing::push( "Draw ImGui" );
ImGui::ShowDemoWindow();
drawDock();
drawCameraOutputs( info );
drawEntityGUI( info );
drawEntityInfo( info );
drawFilesystemGUI( info );
drawStats( info );
}
static GameObject* selected_object { nullptr };
void itterateGameObjectNode( FrameInfo& info, OctTreeNode& node )
@@ -294,23 +190,4 @@ namespace fgl::engine::gui
ImGui::End();
}
void drawFilesystemGUI( FrameInfo& info )
{
ZoneScoped;
ImGui::Begin( FILE_PICKER_NAME, nullptr, ImGuiWindowFlags_MenuBar );
filesystem::FileBrowser::drawGui( info );
ImGui::End();
}
void cleanupImGui()
{
ZoneScoped;
filesystem::destroyFileGui();
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
} // namespace fgl::engine::gui

View File

@@ -16,17 +16,14 @@ namespace fgl::engine
namespace fgl::engine::gui
{
// Setup/Destruction
void initGui( const Window& window, const Renderer& renderer );
void cleanupImGui();
// Draws
void startDrawImGui( FrameInfo& info );
void drawDock();
void drawImGui( FrameInfo& );
void drawEntityGUI( FrameInfo& );
void drawEntityInfo( FrameInfo& );
void drawFilesystemGUI( FrameInfo& info );
void drawObject( GameObject& game_object );
void drawComponentsList( GameObject& game_object );
@@ -36,6 +33,4 @@ namespace fgl::engine::gui
void drawStats( const FrameInfo& info );
void endDrawImGui( FrameInfo& info );
} // namespace fgl::engine::gui

View File

@@ -3,15 +3,18 @@
//
#include <cstdlib>
#include "debug/profiling/counters.hpp"
#include "engine/EngineContext.hpp"
#include "engine/camera/CameraManager.hpp"
#include "engine/debug/timing/FlameGraph.hpp"
#include "engine/gameobjects/components/CameraComponent.hpp"
#include "gui/EditorGuiContext.hpp"
#include "gui/core.hpp"
int main()
{
using namespace fgl::engine;
using namespace fgl::editor;
log::set_level( spdlog::level::debug );
@@ -38,13 +41,18 @@ int main()
try
{
EngineContext engine_ctx {};
EditorGuiContext editor_ctx { engine_ctx.getWindow() };
// We start by hooking into the imgui rendering.
engine_ctx.hookInitImGui( gui::initGui );
engine_ctx.hookPreFrame( gui::startDrawImGui );
engine_ctx.hookEarlyFrame( gui::drawImGui );
engine_ctx.hookLateFrame( gui::endDrawImGui );
engine_ctx.hookDestruction( gui::cleanupImGui );
engine_ctx.hookPreFrame(
[ & ]( [[maybe_unused]] FrameInfo& info )
{
editor_ctx.beginDraw();
profiling::resetCounters();
} );
engine_ctx.hookEarlyFrame( [ & ]( [[maybe_unused]] FrameInfo& info ) { editor_ctx.draw( info ); } );
engine_ctx.hookLateFrame( [ & ]( FrameInfo& info ) { editor_ctx.endDraw( info ); } );
// Now we need to create the camera for the editor.
CameraManager& camera_manager { engine_ctx.cameraManager() };
@@ -78,6 +86,8 @@ int main()
// This will 'end' the root node, Which is created on 'reset'
debug::timing::internal::pop();
}
engine_ctx.waitIdle();
}
catch ( const vk::LayerNotPresentError& e )
{

View File

@@ -10,6 +10,8 @@ AddFGLLibrary(FGLEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURC
target_compile_definitions(FGLEngine PUBLIC VULKAN_HPP_FLAGS_MASK_TYPE_AS_PUBLIC)
target_link_libraries(FGLEngine PUBLIC stdc++exp)
include(dependencies/spdlog)
include(dependencies/imgui)

View File

@@ -45,7 +45,7 @@ namespace fgl::engine
ZoneScoped;
using namespace fgl::literals::size_literals;
memory::TransferManager::createInstance( device, 128_MiB );
// memory::TransferManager::createInstance( device, 128_MiB );
m_matrix_info_pool.setDebugName( "Matrix info pool" );
m_draw_parameter_pool.setDebugName( "Draw parameter pool" );
@@ -216,6 +216,11 @@ namespace fgl::engine
void EngineContext::finishFrame()
{}
void EngineContext::waitIdle()
{
device->waitIdle();
}
Window& EngineContext::getWindow()
{
return m_window;

View File

@@ -7,6 +7,7 @@
#include "Window.hpp"
#include "camera/CameraManager.hpp"
#include "clock.hpp"
#include "engine/assets/transfer/TransferManager.hpp"
#include "engine/math/literals/size.hpp"
#include "engine/rendering/Renderer.hpp"
#include "engine/tree/octtree/OctTreeNode.hpp"
@@ -43,9 +44,6 @@ namespace fgl::engine
Renderer m_renderer { m_window, device.phyDevice() };
//GameObject::Map game_objects {};
OctTreeNode m_game_objects_root { WorldCoordinate( constants::WORLD_CENTER ) };
std::unique_ptr< memory::Buffer > m_vertex_buffer { std::make_unique< memory::Buffer >(
1_GiB,
vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst,
@@ -55,6 +53,11 @@ namespace fgl::engine
vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst,
vk::MemoryPropertyFlagBits::eDeviceLocal ) };
memory::TransferManager m_transfer_manager { device, 128_MiB };
//GameObject::Map game_objects {};
OctTreeNode m_game_objects_root { WorldCoordinate( constants::WORLD_CENTER ) };
// SubPass 0
GuiSystem m_gui_system {};
@@ -130,6 +133,9 @@ namespace fgl::engine
//! Runs any post-frame processes
void finishFrame();
//! Waits for all frames to be completed
void waitIdle();
Window& getWindow();
float getWindowAspectRatio();

View File

@@ -19,29 +19,29 @@ namespace fgl::engine::memory
ZoneScoped;
//Keep inserting new commands until we fill up the staging buffer
if ( queue.size() > 0 ) log::info( "[TransferManager]: Queue size: {}", queue.size() );
if ( m_queue.size() > 0 ) log::info( "[TransferManager]: Queue size: {}", m_queue.size() );
std::size_t counter { 0 };
constexpr std::size_t counter_max { 256 };
while ( queue.size() > 0 )
while ( m_queue.size() > 0 )
{
++counter;
if ( counter > counter_max ) break;
TransferData data { std::move( queue.front() ) };
queue.pop();
TransferData data { std::move( m_queue.front() ) };
m_queue.pop();
if ( data.stage(
command_buffer, *staging_buffer, copy_regions, transfer_queue_index, graphics_queue_index ) )
command_buffer, *m_staging_buffer, m_copy_regions, m_transfer_queue_index, m_graphics_queue_index ) )
{
processing.emplace_back( std::move( data ) );
m_processing.emplace_back( std::move( data ) );
}
else
{
// We were unable to stage for a reason
log::info( "Unable to stage object. Breaking out of loop" );
queue.push( data );
m_queue.push( data );
break;
}
}
@@ -60,7 +60,7 @@ namespace fgl::engine::memory
{} );
//Record all the buffer copies
for ( auto& [ key, regions ] : copy_regions )
for ( auto& [ key, regions ] : m_copy_regions )
{
auto& [ source, target ] = key;
@@ -81,7 +81,7 @@ namespace fgl::engine::memory
void TransferManager::resizeBuffer( const std::uint64_t size )
{
staging_buffer = std::make_unique< Buffer >(
m_staging_buffer = std::make_unique< Buffer >(
size,
vk::BufferUsageFlagBits::eTransferSrc,
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent );
@@ -91,7 +91,7 @@ namespace fgl::engine::memory
{
ZoneScoped;
std::vector< vk::Fence > fences { completion_fence };
std::vector< vk::Fence > fences { m_completion_fence };
Device::getInstance()->resetFences( fences );
@@ -101,18 +101,18 @@ namespace fgl::engine::memory
std::vector< vk::CommandBuffer > buffers { *command_buffer };
std::vector< vk::Semaphore > sems { transfer_semaphore };
std::vector< vk::Semaphore > sems { m_transfer_semaphore };
info.setSignalSemaphores( sems );
info.setCommandBuffers( buffers );
transfer_queue.submit( info, completion_fence );
m_transfer_queue.submit( info, m_completion_fence );
}
std::vector< vk::BufferMemoryBarrier > TransferManager::createFromGraphicsBarriers()
{
std::vector< vk::BufferMemoryBarrier > barriers {};
for ( auto& [ key, regions ] : copy_regions )
for ( auto& [ key, regions ] : m_copy_regions )
{
auto& [ source, target ] = key;
@@ -124,8 +124,8 @@ namespace fgl::engine::memory
barrier.size = region.size;
barrier.srcAccessMask = vk::AccessFlagBits::eNone;
barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
barrier.srcQueueFamilyIndex = graphics_queue_index;
barrier.dstQueueFamilyIndex = transfer_queue_index;
barrier.srcQueueFamilyIndex = m_graphics_queue_index;
barrier.dstQueueFamilyIndex = m_transfer_queue_index;
barriers.emplace_back( barrier );
}
@@ -138,7 +138,7 @@ namespace fgl::engine::memory
{
std::vector< vk::BufferMemoryBarrier > barriers {};
for ( auto& [ key, regions ] : copy_regions )
for ( auto& [ key, regions ] : m_copy_regions )
{
auto& [ source, target ] = key;
@@ -150,8 +150,8 @@ namespace fgl::engine::memory
barrier.size = region.size;
barrier.srcAccessMask = vk::AccessFlagBits::eNone;
barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
barrier.srcQueueFamilyIndex = graphics_queue_index;
barrier.dstQueueFamilyIndex = transfer_queue_index;
barrier.srcQueueFamilyIndex = m_graphics_queue_index;
barrier.dstQueueFamilyIndex = m_transfer_queue_index;
barriers.emplace_back( barrier );
}
@@ -164,7 +164,7 @@ namespace fgl::engine::memory
{
std::vector< vk::BufferMemoryBarrier > barriers {};
for ( auto& [ key, regions ] : copy_regions )
for ( auto& [ key, regions ] : m_copy_regions )
{
auto& [ source, target ] = key;
@@ -176,8 +176,8 @@ namespace fgl::engine::memory
barrier.size = region.size;
barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
barrier.dstAccessMask = vk::AccessFlagBits::eVertexAttributeRead | vk::AccessFlagBits::eIndexRead;
barrier.srcQueueFamilyIndex = transfer_queue_index;
barrier.dstQueueFamilyIndex = graphics_queue_index;
barrier.srcQueueFamilyIndex = m_transfer_queue_index;
barrier.dstQueueFamilyIndex = m_graphics_queue_index;
barriers.emplace_back( barrier );
}
@@ -190,7 +190,7 @@ namespace fgl::engine::memory
{
std::vector< vk::BufferMemoryBarrier > barriers {};
for ( const auto& [ key, regions ] : copy_regions )
for ( const auto& [ key, regions ] : m_copy_regions )
{
const auto& [ src, dst ] = key;
for ( const auto& region : regions )
@@ -202,8 +202,8 @@ namespace fgl::engine::memory
barrier.size = region.size;
barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite,
barrier.dstAccessMask = vk::AccessFlagBits::eIndexRead | vk::AccessFlagBits::eVertexAttributeRead;
barrier.srcQueueFamilyIndex = transfer_queue_index;
barrier.dstQueueFamilyIndex = graphics_queue_index;
barrier.srcQueueFamilyIndex = m_transfer_queue_index;
barrier.dstQueueFamilyIndex = m_graphics_queue_index;
barriers.emplace_back( barrier );
}
@@ -212,7 +212,7 @@ namespace fgl::engine::memory
return barriers;
}
inline static std::unique_ptr< TransferManager > global_transfer_manager {};
inline static TransferManager* GLOBAL_TRANSFER_MANAGER {};
void TransferManager::takeOwnership( vk::raii::CommandBuffer& command_buffer )
{
@@ -241,33 +241,25 @@ namespace fgl::engine::memory
{
//Block on fence
std::vector< vk::Fence > fences { completion_fence };
std::vector< vk::Fence > fences { m_completion_fence };
(void)Device::getInstance()->waitForFences( fences, VK_TRUE, std::numeric_limits< std::size_t >::max() );
processing.clear();
copy_regions.clear();
}
void TransferManager::createInstance( Device& device, std::uint64_t buffer_size )
{
log::info(
"Transfer manager created with a buffer size of {}",
fgl::literals::size_literals::toString( buffer_size ) );
global_transfer_manager = std::make_unique< TransferManager >( device, buffer_size );
m_processing.clear();
m_copy_regions.clear();
}
TransferManager& TransferManager::getInstance()
{
assert( global_transfer_manager );
return *global_transfer_manager;
assert( GLOBAL_TRANSFER_MANAGER );
return *GLOBAL_TRANSFER_MANAGER;
}
void TransferManager::copyToVector( BufferVector& source, BufferVector& target, const std::size_t target_offset )
{
TransferData transfer_data { source.getHandle(), target.getHandle(), target_offset };
queue.emplace( std::move( transfer_data ) );
m_queue.emplace( std::move( transfer_data ) );
}
void TransferManager::copyToImage( std::vector< std::byte >&& data, Image& image )
@@ -277,28 +269,32 @@ namespace fgl::engine::memory
assert( std::get< TransferData::RawData >( transfer_data.m_source ).size() > 0 );
queue.emplace( std::move( transfer_data ) );
m_queue.emplace( std::move( transfer_data ) );
}
TransferManager::TransferManager( Device& device, std::uint64_t buffer_size ) :
transfer_queue_index( device.phyDevice()
m_transfer_queue_index( device.phyDevice()
.queueInfo()
.getIndex( vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics ) ),
graphics_queue_index( device.phyDevice().queueInfo().getIndex( vk::QueueFlagBits::eGraphics ) ),
transfer_queue( device->getQueue( transfer_queue_index, 0 ) ),
transfer_semaphore( device->createSemaphore( {} ) ),
cmd_buffer_allocinfo( Device::getInstance().getCommandPool(), vk::CommandBufferLevel::ePrimary, 1 ),
transfer_buffers( Device::getInstance().device().allocateCommandBuffers( cmd_buffer_allocinfo ) ),
completion_fence( device->createFence( {} ) )
m_graphics_queue_index( device.phyDevice().queueInfo().getIndex( vk::QueueFlagBits::eGraphics ) ),
m_transfer_queue( device->getQueue( m_transfer_queue_index, 0 ) ),
m_transfer_semaphore( device->createSemaphore( {} ) ),
m_cmd_buffer_allocinfo( Device::getInstance().getCommandPool(), vk::CommandBufferLevel::ePrimary, 1 ),
m_transfer_buffers( Device::getInstance().device().allocateCommandBuffers( m_cmd_buffer_allocinfo ) ),
m_completion_fence( device->createFence( {} ) )
{
resizeBuffer( buffer_size );
log::info( "Transfer manager created with size {}", literals::size_literals::toString( buffer_size ) );
GLOBAL_TRANSFER_MANAGER = this;
}
void TransferManager::submitNow()
{
ZoneScoped;
auto& transfer_buffer { transfer_buffers[ 0 ] };
auto& transfer_buffer { m_transfer_buffers[ 0 ] };
transfer_buffer.reset();
vk::CommandBufferBeginInfo info {};
@@ -309,15 +305,15 @@ namespace fgl::engine::memory
submitBuffer( transfer_buffer );
if ( processing.size() > 0 ) log::debug( "Submitted {} objects to be transfered", processing.size() );
if ( m_processing.size() > 0 ) log::debug( "Submitted {} objects to be transfered", m_processing.size() );
for ( auto& processed : processing )
for ( auto& processed : m_processing )
{
processed.markGood();
}
//Drop the data
processing.clear();
m_processing.clear();
}
} // namespace fgl::engine::memory

View File

@@ -34,31 +34,29 @@ namespace fgl::engine::memory
{
//TODO: Ring Buffer
//! Queue of data needing to be transfered and submitted.
std::queue< TransferData > queue {};
std::queue< TransferData > m_queue {};
//! Data actively in flight (Submitted to the DEVICE transfer queue)
std::vector< TransferData > processing {};
std::vector< TransferData > m_processing {};
//! Buffer used for any raw -> buffer transfers
std::unique_ptr< Buffer > staging_buffer {};
private:
std::unique_ptr< Buffer > m_staging_buffer {};
//! Map to store copy regions for processing vectors
CopyRegionMap copy_regions {};
CopyRegionMap m_copy_regions {};
std::uint32_t transfer_queue_index;
std::uint32_t graphics_queue_index;
vk::raii::Queue transfer_queue;
std::uint32_t m_transfer_queue_index;
std::uint32_t m_graphics_queue_index;
vk::raii::Queue m_transfer_queue;
//! Signaled once a transfer completes
vk::raii::Semaphore transfer_semaphore;
vk::raii::Semaphore m_transfer_semaphore;
vk::CommandBufferAllocateInfo cmd_buffer_allocinfo;
vk::CommandBufferAllocateInfo m_cmd_buffer_allocinfo;
std::vector< vk::raii::CommandBuffer > transfer_buffers;
std::vector< vk::raii::CommandBuffer > m_transfer_buffers;
vk::raii::Fence completion_fence;
vk::raii::Fence m_completion_fence;
void recordCommands( vk::raii::CommandBuffer& command_buffer );
@@ -82,7 +80,7 @@ namespace fgl::engine::memory
FGL_DELETE_ALL_RO5( TransferManager );
vk::raii::Semaphore& getFinishedSem() { return transfer_semaphore; }
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 );
@@ -93,7 +91,6 @@ namespace fgl::engine::memory
//! Drops the processed items
void dump();
static void createInstance( Device& device, std::uint64_t buffer_size );
static TransferManager& getInstance();
//! Resizes the staging buffer.
@@ -109,7 +106,7 @@ namespace fgl::engine::memory
device_vector.m_handle,
byte_offset };
queue.emplace( std::move( transfer_data ) );
m_queue.emplace( std::move( transfer_data ) );
}
template < typename T, typename DeviceVectorT >

View File

@@ -7,6 +7,11 @@
namespace fgl::engine
{
GameObject::~GameObject()
{
for ( const auto& component : components ) delete component;
}
GameObject GameObject::createGameObject()
{
static GameObjectID current_id { 0 };

View File

@@ -58,6 +58,8 @@ namespace fgl::engine
public:
~GameObject();
GameObject& operator=( GameObject&& other ) = default;
template < typename T >

View File

@@ -4,8 +4,11 @@
#include "Buffer.hpp"
#include <iostream>
#include "BufferSuballocationHandle.hpp"
#include "align.hpp"
#include "engine/debug/logging/logging.hpp"
#include "engine/memory/buffers/exceptions.hpp"
#include "engine/rendering/devices/Device.hpp"
@@ -19,20 +22,43 @@ namespace fgl::engine::memory
return active_buffers;
}
Buffer::
Buffer( vk::DeviceSize memory_size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags memory_properties ) :
inline static std::uint16_t counter { 0 };
Buffer::Buffer(
vk::DeviceSize memory_size,
const vk::BufferUsageFlags usage,
const vk::MemoryPropertyFlags memory_properties ) :
m_memory_size( memory_size ),
m_usage( usage ),
m_memory_properties( memory_properties )
{
alloc( memory_size );
active_buffers.emplace_back( this );
m_free_blocks.push_back( { 0, memory_size } );
m_free_blocks.emplace_back( 0, memory_size );
}
Buffer::~Buffer()
{
assert( this->m_allocations.size() == 0 );
if ( !m_allocations.empty() )
{
log::critical( "Buffer allocations not empty. {} allocations left", m_allocations.size() );
for ( const auto& [ offset, size ] : m_allocations )
{
log::info( "Stacktrace: Offset at {}", offset );
const auto itter = this->m_allocation_traces.find( offset );
if ( itter == this->m_allocation_traces.end() ) continue;
std::stacktrace trace { itter->second };
std::cout << trace << std::endl;
}
throw std::runtime_error( "Buffer allocations not empty" );
}
dealloc();
if ( const auto itter = std::ranges::find( active_buffers, this ); itter != active_buffers.end() )
active_buffers.erase( itter );
@@ -50,8 +76,9 @@ namespace fgl::engine::memory
vmaDestroyBuffer( Device::getInstance().allocator(), m_buffer, m_allocation );
}
void Buffer::alloc( vk::DeviceSize memory_size )
void Buffer::alloc( const vk::DeviceSize memory_size )
{
assert( !m_debug_name.empty() );
assert( memory_size > 0 );
m_memory_size = memory_size;
vk::BufferCreateInfo buffer_info {};
@@ -180,6 +207,8 @@ namespace fgl::engine::memory
//Add the suballocation
m_allocations.insert_or_assign( offset, memory_size );
m_allocation_traces.insert_or_assign( offset, std::stacktrace::current() );
//If there is any memory left over, Then add it back into the free blocks
if ( size - memory_size > 0 )
m_free_blocks.emplace_back( std::make_pair( offset + memory_size, size - memory_size ) );

View File

@@ -90,6 +90,7 @@ namespace fgl::engine::memory
using AllocationSize = vk::DeviceSize;
std::map< vk::DeviceSize, AllocationSize > m_allocations {};
std::unordered_map< vk::DeviceSize, std::stacktrace > m_allocation_traces {};
//! @brief list of any free blocks
//! @note All blocks are amalgamated to the largest they can expand to.

View File

@@ -403,6 +403,11 @@ namespace fgl::engine
}
}
std::vector< vk::raii::Fence >& PresentSwapChain::getFrameFences()
{
return m_in_flight_fence;
}
PresentSwapChain::~PresentSwapChain()
{}

View File

@@ -72,6 +72,8 @@ namespace fgl::engine
public:
std::vector< vk::raii::Fence >& getFrameFences();
PresentSwapChain( vk::Extent2D windowExtent, PhysicalDevice& phy_dev );
PresentSwapChain( vk::Extent2D windowExtent, std::shared_ptr< PresentSwapChain > previous );

View File

@@ -157,6 +157,9 @@ namespace fgl::engine
std::get< OctTreeNodeLeaf >( m_node_data ).reserve( MAX_NODES_IN_LEAF );
}
OctTreeNode::~OctTreeNode()
{}
void OctTreeNode::split( const int depth )
{
ZoneScoped;

View File

@@ -4,8 +4,8 @@
#pragma once
#include "engine/gameobjects/GameObject.hpp"
#include "engine/primitives/boxes/AxisAlignedBoundingCube.hpp"
#include "gameobjects/GameObject.hpp"
namespace fgl::engine
{
@@ -60,6 +60,8 @@ namespace fgl::engine
OctTreeNode( const OctTreeNode& other ) = delete;
OctTreeNode( OctTreeNode&& other ) = delete;
~OctTreeNode();
OctTreeNode& operator=( const OctTreeNode& ) = delete;
OctTreeNode& operator=( OctTreeNode&& ) = delete;
void clear();