Code cleanup

This commit is contained in:
2025-01-23 18:28:22 -05:00
parent 3c192764b2
commit e9affae3b3
29 changed files with 314 additions and 163 deletions

View File

@@ -78,6 +78,9 @@ namespace fgl::editor
EditorGuiContext::~EditorGuiContext()
{
ZoneScoped;
log::info( "Destroying EditorGUIContext" );
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();

View File

@@ -41,6 +41,8 @@ int main()
try
{
EngineContext engine_ctx {};
/*
EditorGuiContext editor_ctx { engine_ctx.getWindow() };
// We start by hooking into the imgui rendering.
@@ -88,6 +90,7 @@ int main()
}
engine_ctx.waitIdle();
*/
}
catch ( const vk::LayerNotPresentError& e )
{

View File

@@ -25,13 +25,10 @@
namespace fgl::engine
{
constexpr float MAX_DELTA_TIME { 0.5 };
inline static EngineContext* instance { nullptr };
EngineContext::EngineContext() :
m_ubo_buffer_pool( 1_MiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible ),
m_material_data_pool(
1_MiB,
vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eTransferDst,
vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible ),
m_matrix_info_pool(
256_MiB,
vk::BufferUsageFlagBits::eVertexBuffer,
@@ -45,6 +42,8 @@ namespace fgl::engine
ZoneScoped;
using namespace fgl::literals::size_literals;
instance = this;
// memory::TransferManager::createInstance( device, 128_MiB );
m_matrix_info_pool.setDebugName( "Matrix info pool" );
@@ -53,10 +52,6 @@ namespace fgl::engine
m_vertex_buffer->setDebugName( "Vertex buffer" );
m_index_buffer->setDebugName( "Index buffer" );
m_material_data_pool.setDebugName( "Material data pool" );
initMaterialDataVec( m_material_data_pool );
constexpr float offset { 8.0f };
constexpr std::size_t grid_size { 6 };
constexpr float factor_offset { 1.0f / static_cast< float >( grid_size ) };
@@ -236,15 +231,31 @@ namespace fgl::engine
return m_camera_manager;
}
MaterialManager& EngineContext::getMaterialManager()
{
return m_material_manager;
}
EngineContext::~EngineContext()
{
log::info( "Destroying EngineContext" );
// Destroy all objects
m_game_objects_root.clear();
destroyMaterialDataVec();
descriptors::deleteQueuedDescriptors();
log::info( "Performing {} destruction hooks", m_destruction_hooks.size() );
for ( const auto& hook : m_destruction_hooks ) hook();
}
EngineContext& EngineContext::getInstance()
{
assert( instance );
return *instance;
}
bool EngineContext::good()
{
return !m_window.shouldClose();

View File

@@ -5,6 +5,7 @@
#pragma once
#include "Window.hpp"
#include "assets/MaterialManager.hpp"
#include "camera/CameraManager.hpp"
#include "clock.hpp"
#include "engine/assets/transfer/TransferManager.hpp"
@@ -51,8 +52,6 @@ namespace fgl::engine
vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst,
vk::MemoryPropertyFlagBits::eDeviceLocal ) };
memory::TransferManager m_transfer_manager { m_device, 128_MiB };
//GameObject::Map game_objects {};
OctTreeNode m_game_objects_root { WorldCoordinate( constants::WORLD_CENTER ) };
@@ -76,14 +75,16 @@ namespace fgl::engine
// Memory pool for shader uniforms.
memory::Buffer m_ubo_buffer_pool;
memory::Buffer m_material_data_pool;
// Memory pool for matrix info and draw parameters
memory::Buffer m_matrix_info_pool;
memory::Buffer m_draw_parameter_pool;
MaterialManager m_material_manager {};
CameraManager m_camera_manager {};
memory::TransferManager m_transfer_manager { m_device, 128_MiB };
std::chrono::time_point< Clock > m_last_tick { Clock::now() };
double m_delta_time;
@@ -111,6 +112,8 @@ namespace fgl::engine
EngineContext();
~EngineContext();
static EngineContext& getInstance();
bool good();
//! Performs and pending memory transfers
@@ -138,6 +141,7 @@ namespace fgl::engine
float getWindowAspectRatio();
CameraManager& cameraManager();
MaterialManager& getMaterialManager();
};
} // namespace fgl::engine

View File

@@ -0,0 +1,52 @@
//
// Created by kj16609 on 1/23/25.
//
#include "MaterialManager.hpp"
#include "engine/math/literals/size.hpp"
#include "material/Material.hpp"
namespace fgl::engine
{
using namespace fgl::literals::size_literals;
void MaterialManager::update( const std::size_t idx, const DeviceMaterialData& material_data )
{
m_material_data.updateData( idx, material_data );
}
MaterialManager::MaterialManager() :
m_material_data_pool(
1_MiB,
vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eTransferDst,
vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible ),
m_material_data( m_material_data_pool, MAX_MATERIAL_COUNT )
{
m_material_data_pool.setDebugName( "Material data pool" );
}
MaterialManager::~MaterialManager()
{
for ( const auto& track : debug::getTracks( "GPU", "Material" ) )
{
log::info( "Found leftover material: \n{}", track.trace );
}
}
memory::Buffer& MaterialManager::getBuffer()
{
return m_material_data_pool;
}
memory::BufferSuballocation& MaterialManager::getBufferSuballocation()
{
return m_material_data;
}
DeviceVector< DeviceMaterialData >& MaterialManager::getMaterialData()
{
return m_material_data;
}
} // namespace fgl::engine

View File

@@ -0,0 +1,32 @@
//
// Created by kj16609 on 1/23/25.
//
#pragma once
#include "engine/memory/buffers/Buffer.hpp"
#include "memory/buffers/vector/DeviceVector.hpp"
namespace fgl::engine
{
struct DeviceMaterialData;
class MaterialManager
{
memory::Buffer m_material_data_pool;
DeviceVector< DeviceMaterialData > m_material_data;
friend class Material;
void update( std::size_t idx, const DeviceMaterialData& material_data );
public:
MaterialManager();
~MaterialManager();
[[nodiscard]] memory::Buffer& getBuffer();
[[nodiscard]] memory::BufferSuballocation& getBufferSuballocation();
[[nodiscard]] DeviceVector< DeviceMaterialData >& getMaterialData();
};
} // namespace fgl::engine

View File

@@ -8,6 +8,8 @@
#include <memory>
#include "debug/Track.hpp"
namespace fgl::engine
{
namespace memory
@@ -24,6 +26,8 @@ namespace fgl::engine
std::weak_ptr< ImageView > m_view {};
vk::Extent2D m_extent;
debug::Track< "GPU", "Image" > m_track {};
friend class memory::TransferManager;
public:

View File

@@ -4,10 +4,9 @@
#include "Material.hpp"
#include "engine/FrameInfo.hpp"
#include "EngineContext.hpp"
#include "engine/assets/texture/Texture.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/memory/buffers/vector/DeviceVector.hpp"
#include "engine/utility/IDPool.hpp"
namespace fgl::engine
@@ -55,7 +54,11 @@ namespace fgl::engine
Material::Material() : m_id( material_id_counter.getID() )
{
getDescriptorSet().bindArray( 0, getDeviceMaterialGPUData().getHandle(), m_id, sizeof( DeviceMaterialData ) );
getDescriptorSet().bindArray(
0,
EngineContext::getInstance().getMaterialManager().getBufferSuballocation(),
m_id,
sizeof( DeviceMaterialData ) );
getDescriptorSet().update();
}
@@ -83,34 +86,14 @@ namespace fgl::engine
Material::~Material()
{
log::debug( "Destroyed material {}", m_id );
material_id_counter.markUnused( m_id );
}
inline static std::unique_ptr< DeviceVector< DeviceMaterialData > > material_data {};
void initMaterialDataVec( memory::Buffer& buffer )
{
material_data = std::make_unique< DeviceVector< DeviceMaterialData > >( buffer, MAX_MATERIAL_COUNT );
}
void destroyMaterialDataVec()
{
material_data.reset();
}
DeviceVector< DeviceMaterialData >& getDeviceMaterialGPUData()
{
if ( material_data )
return *material_data;
else
throw std::runtime_error( "Material data gpu buffer not initalized!" );
}
void Material::update()
{
auto& data_vec { getDeviceMaterialGPUData() };
data_vec.updateData( m_id, properties.data() );
const auto data { properties.data() };
EngineContext::getInstance().getMaterialManager().update( m_id, data );
}
MaterialID Material::getID() const

View File

@@ -114,10 +114,15 @@ namespace fgl::engine
{
MaterialID m_id;
debug::Track< "GPU", "Material" > m_track {};
Material();
public:
FGL_DELETE_COPY( Material );
FGL_DELETE_MOVE( Material );
MaterialProperties properties {};
bool ready() const;
@@ -134,7 +139,4 @@ namespace fgl::engine
static descriptors::DescriptorSet& getDescriptorSet();
};
DeviceVector< DeviceMaterialData >& getDeviceMaterialGPUData();
void initMaterialDataVec( memory::Buffer& buffer );
void destroyMaterialDataVec();
} // namespace fgl::engine

View File

@@ -48,7 +48,6 @@ namespace fgl::engine
friend class TransferManager;
debug::Track< "GPU", "Texture" > m_gpu_track;
debug::Track< "CPU", "Texture" > m_cpu_track;
//! Key used for the global map keeping track of Textures
using UIDKeyT = std::filesystem::path;

View File

@@ -33,7 +33,11 @@ namespace fgl::engine::memory
m_queue.pop();
if ( data.stage(
command_buffer, *m_staging_buffer, m_copy_regions, m_transfer_queue_index, m_graphics_queue_index ) )
command_buffer,
*m_staging_buffer,
m_copy_regions,
m_transfer_queue_index,
m_graphics_queue_index ) )
{
m_processing.emplace_back( std::move( data ) );
}
@@ -273,9 +277,14 @@ namespace fgl::engine::memory
}
TransferManager::TransferManager( Device& device, std::uint64_t buffer_size ) :
m_staging_buffer(
std::make_unique< Buffer >(
buffer_size,
vk::BufferUsageFlagBits::eTransferSrc,
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent ) ),
m_transfer_queue_index( device.phyDevice()
.queueInfo()
.getIndex( vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics ) ),
.queueInfo()
.getIndex( vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics ) ),
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( {} ) ),
@@ -283,8 +292,6 @@ namespace fgl::engine::memory
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;

View File

@@ -33,15 +33,16 @@ namespace fgl::engine::memory
class TransferManager
{
//TODO: Ring Buffer
//! Buffer used for any raw -> buffer transfers
std::unique_ptr< Buffer > m_staging_buffer {};
//! Queue of data needing to be transfered and submitted.
std::queue< TransferData > m_queue {};
//! Data actively in flight (Submitted to the DEVICE transfer queue)
std::vector< TransferData > m_processing {};
//! Buffer used for any raw -> buffer transfers
std::unique_ptr< Buffer > m_staging_buffer {};
//! Map to store copy regions for processing vectors
CopyRegionMap m_copy_regions {};

View File

@@ -13,6 +13,7 @@
#pragma GCC diagnostic pop
#include "CompositeSwapchain.hpp"
#include "debug/Track.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/memory/buffers/HostSingleT.hpp"
#include "engine/memory/buffers/UniqueFrameSuballocation.hpp"
@@ -49,6 +50,8 @@ namespace fgl::engine
{
inline static CameraIDX m_camera_counter { 0 };
debug::Track< "CPU", "Camera" > m_camera {};
vk::Extent2D m_target_extent;
std::unique_ptr< CompositeSwapchain > m_old_composite_swapchain;
@@ -90,7 +93,7 @@ namespace fgl::engine
std::string m_name;
Matrix< MatrixType::ModelToWorld > frustumTranslationMatrix() const;
[[nodiscard]] Matrix< MatrixType::ModelToWorld > frustumTranslationMatrix() const;
void updateFrustum();
@@ -113,34 +116,37 @@ namespace fgl::engine
~Camera();
CameraIDX getIDX() const;
[[nodiscard]] CameraIDX getIDX() const;
const std::string& getName() const;
[[nodiscard]] const std::string& getName() const;
void setExtent( vk::Extent2D extent );
const Rotation& getRotation() const { return m_transform.rotation; }
[[nodiscard]] const Rotation& getRotation() const { return m_transform.rotation; }
Rotation& getRotation() { return m_transform.rotation; }
const WorldTransform& getTransform() const { return m_transform; }
[[nodiscard]] const WorldTransform& getTransform() const { return m_transform; }
WorldTransform& getTransform() { return m_transform; }
WorldCoordinate getFrustumPosition() const;
const FrustumBase& getBaseFrustum() const { return m_base_frustum; }
[[nodiscard]] const FrustumBase& getBaseFrustum() const { return m_base_frustum; }
//! Returns the frustum of the camera in world space
const Frustum& getFrustumBounds() const { return m_frustum; }
[[nodiscard]] const Frustum& getFrustumBounds() const { return m_frustum; }
const Matrix< MatrixType::CameraToScreen >& getProjectionMatrix() const { return m_projection_matrix; }
[[nodiscard]] const Matrix< MatrixType::CameraToScreen >& getProjectionMatrix() const
{
return m_projection_matrix;
}
const Matrix< MatrixType::WorldToCamera >& getViewMatrix() const { return m_view_matrix; }
[[nodiscard]] const Matrix< MatrixType::WorldToCamera >& getViewMatrix() const { return m_view_matrix; }
Matrix< MatrixType::WorldToScreen > getProjectionViewMatrix() const;
[[nodiscard]] Matrix< MatrixType::WorldToScreen > getProjectionViewMatrix() const;
glm::mat4 getInverseViewMatrix() const { return glm::inverse( m_view_matrix ); }
[[nodiscard]] glm::mat4 getInverseViewMatrix() const { return glm::inverse( m_view_matrix ); }
enum ViewMode
{
@@ -152,7 +158,7 @@ namespace fgl::engine
void setOrthographicProjection( float left, float right, float top, float bottom, float near, float far );
void setPerspectiveProjection( float fovy, float aspect, float near, float far );
Coordinate< CoordinateSpace::World > getPosition() const;
[[nodiscard]] Coordinate< CoordinateSpace::World > getPosition() const;
FGL_FORCE_INLINE NormalVector getUp() const { return -getDown(); }
@@ -184,8 +190,8 @@ namespace fgl::engine
//! Performs the render pass for this camera
void pass( FrameInfo& frame_info );
GBufferSwapchain& getSwapchain() const;
CompositeSwapchain& getCompositeSwapchain() const;
[[nodiscard]] GBufferSwapchain& getSwapchain() const;
[[nodiscard]] CompositeSwapchain& getCompositeSwapchain() const;
void setViewport( const vk::raii::CommandBuffer& command_buffer );
void setScissor( const vk::raii::CommandBuffer& command_buffer );

View File

@@ -3,6 +3,7 @@
//
#include "Track.hpp"
#include <cassert>
#include <unordered_map>
namespace fgl::engine::debug
@@ -29,10 +30,10 @@ namespace fgl::engine::debug
void deregisterTrack( std::string_view group, std::string_view name, std::size_t UID )
{
track_info.erase( UIDS );
assert( track_info.erase( UID ) > 0 && "Unable to find UID" );
}
std::vector< TrackInfo > getTracks( std::string_view group, std::string_view name )
std::vector< TrackInfo > getTracks( const std::string_view group, const std::string_view name )
{
std::vector< TrackInfo > tracks {};
tracks.reserve( track_info.size() );

View File

@@ -185,7 +185,7 @@ namespace fgl::engine::descriptors
write.descriptorCount = 1;
write.descriptorType = vk::DescriptorType::eInputAttachment;
write.pBufferInfo = VK_NULL_HANDLE;
write.pImageInfo = &( std::get< vk::DescriptorImageInfo >( m_infos.data()[ binding_idx ] ) );
write.pImageInfo = &( std::get< vk::DescriptorImageInfo >( m_infos[ binding_idx ] ) );
write.pTexelBufferView = VK_NULL_HANDLE;
descriptor_writes.push_back( write );
@@ -205,7 +205,7 @@ namespace fgl::engine::descriptors
void queueDescriptorDeletion( std::unique_ptr< DescriptorSet > set )
{
QUEUE.emplace_back( std::make_pair( 0, std::move( set ) ) );
QUEUE.emplace_back( 0, std::move( set ) );
}
void deleteQueuedDescriptors()

View File

@@ -9,7 +9,34 @@ namespace fgl::engine
GameObject::~GameObject()
{
for ( const auto& component : components ) delete component;
if ( m_id != INVALID_ID )
{
log::debug( "Destroyed game object {}", this->m_id );
for ( const auto& component : components ) delete component;
}
}
GameObject& GameObject::operator=( GameObject&& other ) noexcept
{
m_id = other.m_id;
object_flags = other.object_flags;
m_transform = other.m_transform;
components = std::move( other.components );
m_name = std::move( other.m_name );
other.m_id = INVALID_ID;
return *this;
}
GameObject::GameObject( GameObject&& other ) noexcept :
m_id( other.m_id ),
object_flags( other.object_flags ),
m_transform( other.m_transform ),
components( std::move( other.components ) ),
m_name( other.m_name )
{
other.m_id = INVALID_ID;
}
GameObject GameObject::createGameObject()
@@ -18,27 +45,4 @@ namespace fgl::engine
return GameObject( current_id++ );
}
/*
void GameObject::drawImGui()
{
ImGui::InputText( "Name", &( this->getName() ) );
// Transform - Position
WorldCoordinate& translation { this->m_transform.translation };
gui::dragFloat3( "Position", translation.vec() );
Rotation& rotation { this->m_transform.rotation };
gui::dragFloat3Rot( "Rotation", rotation );
auto& scale { this->m_transform.scale };
gui::dragFloat3( "Scale", scale );
for ( ComponentImGuiInterface* component : components )
{
ImGui::Separator();
component->drawImGui();
}
}
*/
} // namespace fgl::engine

View File

@@ -60,7 +60,8 @@ namespace fgl::engine
~GameObject();
GameObject& operator=( GameObject&& other ) = default;
GameObject& operator=( GameObject&& other ) noexcept;
GameObject( GameObject&& other ) noexcept;
template < typename T >
requires is_component< T >
@@ -71,7 +72,6 @@ namespace fgl::engine
Scale& getScale() { return m_transform.scale; }
GameObject( GameObject&& other ) = default;
template < typename T >
requires is_component< T >

View File

@@ -22,8 +22,6 @@ namespace fgl::engine::memory
return active_buffers;
}
inline static std::uint16_t counter { 0 };
Buffer::Buffer(
vk::DeviceSize memory_size,
const vk::BufferUsageFlags usage,
@@ -45,7 +43,7 @@ namespace fgl::engine::memory
for ( const auto& [ offset, size ] : m_allocations )
{
log::info( "Stacktrace: Offset at {}", offset );
log::info( "Stacktrace: Offset at {} with a size of {}", offset, size );
const auto itter = this->m_allocation_traces.find( offset );
@@ -60,6 +58,7 @@ namespace fgl::engine::memory
}
dealloc();
if ( const auto itter = std::ranges::find( active_buffers, this ); itter != active_buffers.end() )
active_buffers.erase( itter );
}
@@ -155,27 +154,29 @@ namespace fgl::engine::memory
}
std::shared_ptr< BufferSuballocationHandle > Buffer::
allocate( vk::DeviceSize memory_size, const std::uint32_t t_alignment )
allocate( vk::DeviceSize desired_memory_size, const std::uint32_t t_alignment )
{
ZoneScoped;
//Calculate alignment from alignment, ubo_alignment, and atom_size_alignment
memory_size = align( memory_size, alignment() );
desired_memory_size = align( desired_memory_size, alignment() );
assert( desired_memory_size <= this->size() );
//findAvailableBlock( memory_size, t_alignment );
if ( !canAllocate( memory_size, t_alignment ) )
if ( !canAllocate( desired_memory_size, t_alignment ) )
{
//TODO: Write more detailed error message
throw BufferOOM();
}
auto itter { findAvailableBlock( memory_size, t_alignment ) };
auto itter { findAvailableBlock( desired_memory_size, t_alignment ) };
if ( itter == m_free_blocks.end() )
{
//If we can't find a block, then we need to merge the free blocks and try again
mergeFreeBlocks();
itter = findAvailableBlock( memory_size, t_alignment );
itter = findAvailableBlock( desired_memory_size, t_alignment );
}
//TODO: Move this error stuff into the exception message
@@ -185,33 +186,45 @@ namespace fgl::engine::memory
}
//Allocate
auto [ offset, size ] = *itter;
auto [ selected_block_offset, selected_block_size ] = *itter;
m_free_blocks.erase( itter );
const auto aligned_offset { align( offset, alignment(), t_alignment ) };
assert( selected_block_offset <= this->size() );
assert( selected_block_size <= this->size() );
const auto aligned_offset { align( selected_block_offset, alignment(), t_alignment ) };
//Fix the offset and size if they aren't alligned
if ( aligned_offset != offset )
if ( aligned_offset != selected_block_offset )
{
//Insert the space left over before the block starts back into the free blocks
const std::size_t leftover_start_size { aligned_offset - offset };
const std::size_t leftover_start_size { aligned_offset - selected_block_offset };
m_free_blocks.emplace_back( std::make_pair( offset, leftover_start_size ) );
m_free_blocks.emplace_back( std::make_pair( selected_block_offset, leftover_start_size ) );
mergeFreeBlocks();
offset = aligned_offset;
size -= leftover_start_size;
selected_block_offset = aligned_offset;
assert( selected_block_size >= leftover_start_size );
selected_block_size -= leftover_start_size;
}
//Add the suballocation
m_allocations.insert_or_assign( offset, memory_size );
m_allocations.insert_or_assign( selected_block_offset, desired_memory_size );
m_allocation_traces.insert_or_assign( offset, std::stacktrace::current() );
m_allocation_traces.insert_or_assign( selected_block_offset, std::stacktrace::current() );
assert( selected_block_size >= desired_memory_size );
assert( selected_block_size <= this->size() );
//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 ) );
if ( ( selected_block_size >= desired_memory_size ) && ( selected_block_size - desired_memory_size > 0 ) )
{
assert( selected_block_size - desired_memory_size <= this->size() );
m_free_blocks
.emplace_back( selected_block_offset + desired_memory_size, selected_block_size - desired_memory_size );
}
#ifndef NDEBUG
//Check that we haven't lost any memory
@@ -229,7 +242,7 @@ namespace fgl::engine::memory
assert( sum == this->size() );
#endif
return std::make_shared< BufferSuballocationHandle >( *this, offset, memory_size );
return std::make_shared< BufferSuballocationHandle >( *this, selected_block_offset, desired_memory_size );
}
bool Buffer::canAllocate( const vk::DeviceSize memory_size, const std::uint32_t alignment )
@@ -254,7 +267,8 @@ namespace fgl::engine::memory
if ( m_free_blocks.size() <= 1 ) return;
//Sort the blocks by offset
std::ranges::sort( m_free_blocks, []( const auto& a, const auto& b ) -> bool { return a.first < b.first; } );
std::ranges::
sort( m_free_blocks, []( const auto& a, const auto& b ) noexcept -> bool { return a.first < b.first; } );
auto itter { m_free_blocks.begin() };
auto next_block { std::next( itter ) };
@@ -314,8 +328,12 @@ namespace fgl::engine::memory
//Remove the suballocation
m_allocations.erase( itter );
if ( info.m_offset >= this->size() ) throw std::runtime_error( "Offset was outside of bounds of buffer" );
if ( info.m_offset + info.m_size >= this->size() )
throw std::runtime_error( "Offset + m_size was outside of bounds of buffer" );
//Add the block back to the free blocks
m_free_blocks.emplace_back( std::make_pair( info.m_offset, info.m_size ) );
m_free_blocks.emplace_back( info.m_offset, info.m_size );
mergeFreeBlocks();
@@ -332,7 +350,9 @@ namespace fgl::engine::memory
sum += allocated.second;
}
assert( sum == this->size() );
if ( sum != this->size() )
throw std::runtime_error(
std::format( "Memory leaked! Expected {} was {}", static_cast< std::size_t >( this->size() ), sum ) );
#endif
}

View File

@@ -15,6 +15,7 @@
#include <stacktrace>
#include <unordered_map>
#include "engine/debug/Track.hpp"
#include "vma/vma_impl.hpp"
namespace fgl::engine
@@ -44,6 +45,8 @@ namespace fgl::engine::memory
VmaAllocation m_allocation {};
VmaAllocationInfo m_alloc_info {};
debug::Track< "GPU", "Buffer" > m_track {};
vk::DeviceSize m_memory_size;
vk::BufferUsageFlags m_usage;
@@ -124,7 +127,7 @@ namespace fgl::engine::memory
//! Returns a allocation block from this buffer. Block will be aligned with nonUniformBufferOffsetAlignment
//! and nonCoherentAtomSize if required (is_uniform_buffer and is_host_visible respectively)
/**
* @param memory_size Size of each N
* @param desired_memory_size Size of each N
* @param alignment The alignment to use.
* @param source_loc Source location.
* @return
@@ -137,7 +140,7 @@ namespace fgl::engine::memory
* @note Alignment for atom_size is 0 if buffer is not host visible
*/
std::shared_ptr< BufferSuballocationHandle >
allocate( vk::DeviceSize memory_size, std::uint32_t alignment = 1 );
allocate( vk::DeviceSize desired_memory_size, std::uint32_t alignment = 1 );
bool canAllocate( vk::DeviceSize memory_size, std::uint32_t alignment = 1 );

View File

@@ -32,7 +32,9 @@ namespace fgl::engine::memory
m_handle( std::move( handle ) ),
m_offset( m_handle->m_offset ),
m_byte_size( m_handle->m_size )
{}
{
if ( handle.use_count() > 30 ) throw std::runtime_error( "AAAAAAAAA" );
}
BufferSuballocation::BufferSuballocation( BufferSuballocation&& other ) noexcept :
m_handle( std::move( other.m_handle ) ),
@@ -48,19 +50,19 @@ namespace fgl::engine::memory
void* BufferSuballocation::ptr() const
{
assert( m_handle != nullptr );
FGL_ASSERT( m_handle->mapped, "Buffer must be mappable to use `ptr()`" );
return m_handle->mapped;
FGL_ASSERT( m_handle->m_ptr, "Buffer must be mappable to use `ptr()`" );
return m_handle->m_ptr;
}
void BufferSuballocation::flush( const vk::DeviceSize beg, const vk::DeviceSize end ) const
{
assert( beg < end );
assert( m_handle != nullptr );
assert( m_handle->mapped != nullptr && "BufferSuballocationT::flush() called before map()" );
assert( m_handle->m_ptr != nullptr && "BufferSuballocationT::flush() called before map()" );
assert( end <= this->m_byte_size );
vk::MappedMemoryRange range {};
range.memory = m_handle->buffer.getMemory();
range.memory = m_handle->m_buffer.getMemory();
range.offset = m_offset + beg;
const vk::DeviceSize min_atom_size { Device::getInstance().m_properties.limits.nonCoherentAtomSize };
@@ -83,14 +85,14 @@ namespace fgl::engine::memory
{
assert( m_handle != nullptr );
return m_handle->buffer;
return m_handle->m_buffer;
}
vk::Buffer BufferSuballocation::getVkBuffer() const
{
assert( m_handle != nullptr );
return m_handle->buffer.getVkBuffer();
return m_handle->m_buffer.getVkBuffer();
}
vk::DescriptorBufferInfo BufferSuballocation::descriptorInfo( const std::size_t byte_offset ) const
@@ -101,6 +103,12 @@ namespace fgl::engine::memory
return vk::DescriptorBufferInfo( getVkBuffer(), m_offset + byte_offset, m_byte_size );
}
BufferSuballocation::~BufferSuballocation()
{
if ( m_handle.use_count() > 1 ) [[unlikely]]
log::debug( "Destroyed buffer suballocation with {} use counts", m_handle.use_count() );
}
SuballocationView BufferSuballocation::view( const vk::DeviceSize offset, const vk::DeviceSize size ) const
{
assert( m_handle != nullptr );

View File

@@ -5,6 +5,7 @@
#pragma once
#include "BufferSuballocationHandle.hpp"
#include "debug/Track.hpp"
#include "engine/rendering/devices/Device.hpp"
namespace fgl::engine::memory
@@ -18,6 +19,8 @@ namespace fgl::engine::memory
{
std::shared_ptr< BufferSuballocationHandle > m_handle;
debug::Track< "GPU", "BufferSuballocation" > m_track {};
friend class TransferManager;
protected:
@@ -36,15 +39,14 @@ namespace fgl::engine::memory
BufferSuballocation() = delete;
BufferSuballocation( std::shared_ptr< BufferSuballocationHandle > handle );
BufferSuballocation( Buffer& buffer, const vk::DeviceSize size );
BufferSuballocation( Buffer& buffer, vk::DeviceSize size );
BufferSuballocation( const BufferSuballocation& ) = delete;
BufferSuballocation& operator=( const BufferSuballocation& ) = delete;
FGL_DELETE_COPY( BufferSuballocation );
BufferSuballocation( BufferSuballocation&& other ) noexcept;
BufferSuballocation& operator=( BufferSuballocation&& other ) noexcept;
SuballocationView view( const vk::DeviceSize offset, const vk::DeviceSize size ) const;
SuballocationView view( vk::DeviceSize offset, vk::DeviceSize size ) const;
//! Returns true when the buffer has been staged by the StagingManager
bool ready() const { return m_handle->ready(); }
@@ -68,7 +70,7 @@ namespace fgl::engine::memory
const std::shared_ptr< BufferSuballocationHandle >& getHandle() { return m_handle; }
~BufferSuballocation() = default;
~BufferSuballocation();
};
} // namespace fgl::engine::memory

View File

@@ -12,27 +12,27 @@ namespace fgl::engine::memory
{
vk::Buffer BufferSuballocationHandle::getBuffer() const
{
return buffer.getVkBuffer();
return m_buffer.getVkBuffer();
}
BufferSuballocationHandle::
BufferSuballocationHandle( Buffer& p_buffer, const vk::DeviceSize offset, const vk::DeviceSize memory_size ) :
buffer( p_buffer ),
m_buffer( p_buffer ),
m_size( memory_size ),
m_offset( offset ),
mapped( buffer.map( *this ) )
m_ptr( m_buffer.map( *this ) )
{
assert( memory_size != 0 && "BufferSuballocation::BufferSuballocation() called with memory_size == 0" );
}
vk::Buffer BufferSuballocationHandle::getVkBuffer() const
{
return buffer.getVkBuffer();
return m_buffer.getVkBuffer();
}
BufferSuballocationHandle::~BufferSuballocationHandle()
{
buffer.free( *this );
m_buffer.free( *this );
}
vk::BufferCopy BufferSuballocationHandle::

View File

@@ -8,6 +8,8 @@
#include <memory>
#include "engine/debug/Track.hpp"
namespace vk::raii
{
class CommandBuffer;
@@ -19,7 +21,9 @@ namespace fgl::engine::memory
struct BufferSuballocationHandle
{
Buffer& buffer;
Buffer& m_buffer;
debug::Track< "GPU", "BufferSuballocationHandle" > m_track {};
//! Size of the buffer this suballocation is a part of
vk::DeviceSize m_size;
@@ -27,7 +31,7 @@ namespace fgl::engine::memory
//! Offset within buffer
vk::DeviceSize m_offset;
void* mapped { nullptr };
void* m_ptr { nullptr };
bool m_staged { false };
@@ -42,15 +46,17 @@ namespace fgl::engine::memory
BufferSuballocationHandle( BufferSuballocationHandle&& ) = delete;
BufferSuballocationHandle& operator=( BufferSuballocationHandle&& ) = delete;
vk::Buffer getBuffer() const;
vk::Buffer getVkBuffer() const;
[[nodiscard]] vk::Buffer getBuffer() const;
[[nodiscard]] vk::Buffer getVkBuffer() const;
vk::BufferCopy copyRegion( const BufferSuballocationHandle& target, std::size_t offset ) const;
[[nodiscard]] vk::BufferCopy copyRegion( const BufferSuballocationHandle& target, std::size_t offset ) const;
vk::DeviceSize getOffset() const { return m_offset; }
void copyTo( const vk::raii::CommandBuffer& cmd_buffer,
const BufferSuballocationHandle& other, std::size_t offset ) const;
void copyTo(
const vk::raii::CommandBuffer& cmd_buffer,
const BufferSuballocationHandle& other,
std::size_t offset ) const;
bool ready() const { return m_staged; }

View File

@@ -10,13 +10,10 @@
#include "engine/debug/logging/logging.hpp"
#include "engine/math/literals/size.hpp"
namespace fgl::engine
namespace fgl::engine::memory
{
namespace memory
{
class Buffer;
}
} // namespace fgl::engine
class Buffer;
}
namespace fgl::engine
{
@@ -34,6 +31,9 @@ namespace fgl::engine
assert( count != 0 && "BufferSuballocationVector::BufferSuballocationVector() called with count == 0" );
}
FGL_DELETE_COPY( DeviceVector );
FGL_DEFAULT_MOVE( DeviceVector );
/**
* @brief Constructs a new DeviceVector from a vector using an allocation of the supplied buffer
* @param buffer buffer to allocate from

View File

@@ -168,7 +168,6 @@ namespace fgl::engine
log::info( "Validation layers enabled" );
}
return extensions;
}

View File

@@ -186,11 +186,13 @@ namespace fgl::engine
Device::~Device()
{
vmaDestroyAllocator( m_allocator );
const auto leftover_tracks { debug::getAllTracks() };
for ( auto& track : leftover_tracks )
{
log::critical( "Important allocation leftover from {}", track.trace );
log::critical( "Important allocation leftover from {}:{}\n{}", track.group, track.name, track.trace );
}
}

View File

@@ -141,8 +141,6 @@ namespace fgl::engine
return pipeline;
}
descriptors::DescriptorSetLayout empty_set_layout { descriptors::DescriptorSetLayout::createEmptySet() };
vk::raii::PipelineLayout PipelineBuilder::createLayout()
{
vk::PipelineLayoutCreateInfo info {};
@@ -169,13 +167,11 @@ namespace fgl::engine
if ( itter == m_state->descriptor_set_layouts.end() )
{
// Could not find it. Empty
set_layouts[ i ] = empty_set_layout.layout();
continue;
set_layouts[ i ] = m_empty_set_layout.layout();
}
else
{
set_layouts[ i ] = itter->second;
continue;
}
}
@@ -190,7 +186,7 @@ namespace fgl::engine
}
void PipelineBuilder::
addDescriptorSet( const SetID idx, const vk::raii::DescriptorSetLayout& descriptor_set_layout )
addDescriptorSet( const SetID idx, const vk::raii::DescriptorSetLayout& descriptor_set_layout ) const
{
FGL_ASSERT( !m_state->descriptor_set_layouts.contains( idx ), "Descriptor already set!" );
m_state->descriptor_set_layouts.insert( std::make_pair( idx, *descriptor_set_layout ) );
@@ -198,7 +194,7 @@ namespace fgl::engine
void PipelineBuilder::addDescriptorSet( descriptors::DescriptorSetLayout& descriptor )
{
return addDescriptorSet( descriptor.m_set_idx, descriptor.layout() );
addDescriptorSet( descriptor.m_set_idx, descriptor.layout() );
}
void PipelineBuilder::addDynamicState( vk::DynamicState dynamic_state )
@@ -313,7 +309,7 @@ namespace fgl::engine
}
void PipelineBuilder::
setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& descriptions )
setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& descriptions ) const
{
m_state->vertex_input_descriptions.attributes = descriptions;
}

View File

@@ -9,6 +9,7 @@
#include <cstdint>
#include <unordered_map>
#include "descriptors/DescriptorSetLayout.hpp"
#include "engine/FGL_DEFINES.hpp"
#include "engine/rendering/pipelines/Shader.hpp"
@@ -29,9 +30,11 @@ namespace fgl::engine
vk::raii::PipelineLayout createLayout();
descriptors::DescriptorSetLayout m_empty_set_layout { descriptors::DescriptorSetLayout::createEmptySet() };
public:
void addDescriptorSet( SetID idx, const vk::raii::DescriptorSetLayout& descriptor_set_layout );
void addDescriptorSet( SetID idx, const vk::raii::DescriptorSetLayout& descriptor_set_layout ) const;
void addDescriptorSet( descriptors::DescriptorSetLayout& descriptor );
void addDynamicState( vk::DynamicState dynamic_state );
void setPushConstant( vk::ShaderStageFlags flags, std::size_t size );
@@ -108,7 +111,7 @@ namespace fgl::engine
void setBindingDescriptions( const std::vector< vk::VertexInputBindingDescription >& descriptions );
void setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& descriptions );
void setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& descriptions ) const;
PipelineBuilder( std::uint32_t subpass );

View File

@@ -17,7 +17,7 @@ namespace fgl::engine::debug
[[nodiscard]] constexpr const char* c_str() const { return m_data; }
operator std::string_view() const { return std::string_view { m_data, N }; }
operator std::string_view() const { return std::string_view { m_data, N - 1 }; }
TString() = delete;
TString( const TString& ) = delete;