From 52f4ae3e44a9db41088d8aac31b499ce454aa35d Mon Sep 17 00:00:00 2001 From: kj16609 Date: Fri, 4 Jul 2025 07:41:59 -0400 Subject: [PATCH] Cleanup more transfer buffer things --- src/editor/src/components/ModelComponent.cpp | 12 +++++ src/editor/src/gui/core.cpp | 25 +++++++-- src/editor/src/gui/preview.cpp | 12 ++--- src/editor/src/main.cpp | 9 ++-- src/engine/EngineContext.cpp | 2 +- src/engine/EngineContext.hpp | 4 +- src/engine/FrameInfo.hpp | 2 +- src/engine/assets/model/Model.cpp | 12 ++--- src/engine/assets/model/Model.hpp | 2 + src/engine/assets/model/ModelInstance.hpp | 7 +++ .../assets/model/builders/SceneBuilder.cpp | 18 +++---- .../assets/model/builders/SceneBuilder.hpp | 4 +- src/engine/assets/transfer/TransferData.cpp | 14 ++--- .../assets/transfer/TransferManager.cpp | 18 +++++++ .../assets/transfer/TransferManager.hpp | 19 ++----- src/engine/gameobjects/GameObject.cpp | 4 +- src/engine/gameobjects/GameObject.hpp | 2 +- src/engine/memory/buffers/BufferHandle.cpp | 42 +++++++-------- src/engine/memory/buffers/BufferHandle.hpp | 32 ++++++++--- .../buffers/BufferSuballocationHandle.cpp | 34 +++++++++++- .../buffers/BufferSuballocationHandle.hpp | 53 ++++++++++++------- .../memory/buffers/SuballocationView.cpp | 4 +- .../memory/buffers/SuballocationView.hpp | 2 +- 23 files changed, 218 insertions(+), 115 deletions(-) diff --git a/src/editor/src/components/ModelComponent.cpp b/src/editor/src/components/ModelComponent.cpp index 8279c81..4835480 100644 --- a/src/editor/src/components/ModelComponent.cpp +++ b/src/editor/src/components/ModelComponent.cpp @@ -17,6 +17,18 @@ namespace fgl::engine::components void ModelComponent::drawImGui() { + ImGui::Text( "Primitives: " ); + ImGui::SameLine(); + ImGui::Text( "%li", m_model_instance->m_model->m_primitives.size() ); + + // list each primitive and list the buffer that it is stored in + for ( const auto& primitive : m_model_instance->m_model->m_primitives ) + { + ImGui::Text( "Primitive: %s", primitive.m_name.c_str() ); + ImGui::SameLine(); + ImGui::Text( "Buffer: %s", primitive.m_vertex_buffer.getBuffer()->sizeName().c_str() ); + } + // drawComponentTransform( m_transform ); // TODO: If the model is not set then we should be able to set it to one from the file selection diff --git a/src/editor/src/gui/core.cpp b/src/editor/src/gui/core.cpp index 45a82e7..b077399 100644 --- a/src/editor/src/gui/core.cpp +++ b/src/editor/src/gui/core.cpp @@ -11,6 +11,7 @@ #include // Included for DockBuilder since it's not exposed yet #pragma GCC diagnostic pop +#include "EngineContext.hpp" #include "FileBrowser.hpp" #include "engine/assets/model/Model.hpp" #include "engine/debug/DEBUG_NAMES.hpp" @@ -95,7 +96,7 @@ namespace fgl::engine::gui // ImGui::PopStyleVar(); } - static GameObject* selected_object { nullptr }; + static std::weak_ptr< GameObject > selected_object {}; void itterateGameObjectNode( FrameInfo& info, OctTreeNode& node ) { @@ -152,6 +153,20 @@ namespace fgl::engine::gui ZoneScoped; ImGui::Begin( OBJECT_TREE_VIEW_NAME ); + auto& game_objects { info.m_game_objects }; + + for ( auto& object : game_objects ) + { + ImGui::PushID( object->getId() ); + + if ( ImGui::Selectable( object->getName().c_str() ) ) + { + selected_object = object; + } + + ImGui::PopID(); + } + // itterateGameObjectNode( info, info.game_objects ); /* @@ -179,14 +194,16 @@ namespace fgl::engine::gui ZoneScoped; ImGui::Begin( ENTITY_INFO_NAME ); - if ( !selected_object ) + if ( selected_object.expired() ) { ImGui::End(); return; } - drawObject( *selected_object ); - drawComponentsList( *selected_object ); + const auto object { selected_object.lock() }; + + drawObject( *object ); + drawComponentsList( *object ); ImGui::End(); } diff --git a/src/editor/src/gui/preview.cpp b/src/editor/src/gui/preview.cpp index d1e6cab..24f5636 100644 --- a/src/editor/src/gui/preview.cpp +++ b/src/editor/src/gui/preview.cpp @@ -42,19 +42,19 @@ namespace fgl::engine::gui case filesystem::MODEL: { // Load model and drop it into the game objects - GameObject obj { GameObject::createGameObject() }; + auto obj { GameObject::createGameObject() }; std::shared_ptr< Model > model { Model::createModel( data->m_path ) }; - obj.addFlag( IsEntity | IsVisible ); + obj->addFlag( IsEntity | IsVisible ); // info.context.models().loadModel( data->m_path ); auto component { std::make_unique< components::ModelComponent >( model ) }; - obj.addComponent( std::move( component ) ); + obj->addComponent( std::move( component ) ); - info.game_objects.emplace_back( std::move( obj ) ); + info.m_game_objects.emplace_back( std::move( obj ) ); break; } @@ -65,11 +65,11 @@ namespace fgl::engine::gui builder.loadScene( data->m_path ); - std::vector< GameObject > objs { builder.getGameObjects() }; + std::vector< std::shared_ptr< GameObject > > objs { builder.getGameObjects() }; for ( auto& obj : objs ) { - info.game_objects.emplace_back( std::move( obj ) ); + info.m_game_objects.emplace_back( std::move( obj ) ); } } } diff --git a/src/editor/src/main.cpp b/src/editor/src/main.cpp index f9cf690..fb08060 100644 --- a/src/editor/src/main.cpp +++ b/src/editor/src/main.cpp @@ -8,7 +8,6 @@ #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" int main() @@ -80,19 +79,19 @@ int main() builder.loadScene( sponza_path ); - std::vector< GameObject > objs { builder.getGameObjects() }; + std::vector< std::shared_ptr< GameObject > > objs { builder.getGameObjects() }; for ( auto& obj : objs ) { - if ( obj.hasComponent< components::ModelComponent >() ) + if ( obj->hasComponent< components::ModelComponent >() ) { - auto model_components { obj.getComponents< components::ModelComponent >() }; + auto model_components { obj->getComponents< components::ModelComponent >() }; for ( auto& component : model_components ) {} } - engine_ctx.game_objects.emplace_back( std::move( obj ) ); + engine_ctx.m_game_objects.emplace_back( std::move( obj ) ); } } diff --git a/src/engine/EngineContext.cpp b/src/engine/EngineContext.cpp index 9ab7899..cbf6cff 100644 --- a/src/engine/EngineContext.cpp +++ b/src/engine/EngineContext.cpp @@ -150,7 +150,7 @@ namespace fgl::engine *m_model_buffers.m_instances_desc, *m_gpu_draw_cmds_desc[ in_flight_idx ], m_gpu_draw_commands[ in_flight_idx ], - game_objects, + m_game_objects, this->m_renderer.getSwapChain() }; { diff --git a/src/engine/EngineContext.hpp b/src/engine/EngineContext.hpp index 1b54d48..5119b7a 100644 --- a/src/engine/EngineContext.hpp +++ b/src/engine/EngineContext.hpp @@ -72,7 +72,7 @@ namespace fgl::engine public: - std::vector< GameObject > game_objects {}; + std::vector< std::shared_ptr< GameObject > > m_game_objects {}; ModelGPUBuffers m_model_buffers {}; @@ -87,7 +87,7 @@ namespace fgl::engine CameraManager m_camera_manager {}; - memory::TransferManager m_transfer_manager { m_device, 32_MiB }; + memory::TransferManager m_transfer_manager { m_device, 512_MiB }; std::chrono::time_point< Clock > m_last_tick { Clock::now() }; DeltaTime m_delta_time; diff --git a/src/engine/FrameInfo.hpp b/src/engine/FrameInfo.hpp index 5a79450..29ae8eb 100644 --- a/src/engine/FrameInfo.hpp +++ b/src/engine/FrameInfo.hpp @@ -96,7 +96,7 @@ namespace fgl::engine //! Populated commands buffer by the culling pass DeviceVector< vk::DrawIndexedIndirectCommand >& m_commands; - std::vector< GameObject >& game_objects; + std::vector< std::shared_ptr< GameObject > >& m_game_objects; // descriptors::DescriptorSet& gui_input_descriptor; diff --git a/src/engine/assets/model/Model.cpp b/src/engine/assets/model/Model.cpp index 694aaf1..77c760b 100644 --- a/src/engine/assets/model/Model.cpp +++ b/src/engine/assets/model/Model.cpp @@ -30,12 +30,12 @@ namespace fgl::engine vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible ), m_vertex_buffer( - 2_GiB, + 2_MiB, vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal ), m_index_buffer( - 1_GiB, + 1_MiB, vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal ), m_generated_instance_info( constructPerFrame< DeviceVector< PerVertexInstanceInfo > >( m_vertex_buffer ) ), @@ -43,7 +43,7 @@ namespace fgl::engine m_primitive_instances( m_short_buffer ), m_model_instances( m_short_buffer ) { - m_vertex_buffer->setDebugName( "Vertex buffer" ); + m_vertex_buffer->setDebugName( "Vertex buffer GPU" ); m_index_buffer->setDebugName( "Index buffer" ); m_primitives_desc = PRIMITIVE_SET.create(); @@ -103,14 +103,14 @@ namespace fgl::engine ModelInstanceInfoIndex model_instance { buffers.m_model_instances.acquire( model_info ) }; - for ( std::size_t i = 0; i < m_primitives.size(); i++ ) + for ( auto& primitive : m_primitives ) { - auto render_info { m_primitives[ i ].renderInstanceInfo() }; + const auto render_info { primitive.renderInstanceInfo() }; PrimitiveInstanceInfo instance_info {}; instance_info.m_primitive_info = render_info->idx(); instance_info.m_model_info = model_instance.idx(); - instance_info.m_material = m_primitives[ i ].default_material->getID(); + instance_info.m_material = primitive.default_material->getID(); primitive_instances.emplace_back( buffers.m_primitive_instances.acquire( instance_info ) ); } diff --git a/src/engine/assets/model/Model.hpp b/src/engine/assets/model/Model.hpp index bc45ea4..6375a09 100644 --- a/src/engine/assets/model/Model.hpp +++ b/src/engine/assets/model/Model.hpp @@ -126,6 +126,8 @@ namespace fgl::engine std::vector< Primitive > m_primitives {}; + friend class components::ModelComponent; + public: Model( std::vector< Primitive >&& primitives, const std::string& name = {} ); diff --git a/src/engine/assets/model/ModelInstance.hpp b/src/engine/assets/model/ModelInstance.hpp index ba165c8..1eb3e18 100644 --- a/src/engine/assets/model/ModelInstance.hpp +++ b/src/engine/assets/model/ModelInstance.hpp @@ -10,6 +10,11 @@ namespace fgl::engine { + namespace components + { + class ModelComponent; + } + class Model; using InstanceIndex = std::uint32_t; @@ -24,6 +29,8 @@ namespace fgl::engine //! True if the last frame changed this instance in any way bool m_updated { false }; + friend class components::ModelComponent; + public: ModelInstance( diff --git a/src/engine/assets/model/builders/SceneBuilder.cpp b/src/engine/assets/model/builders/SceneBuilder.cpp index b341b60..fbbc805 100644 --- a/src/engine/assets/model/builders/SceneBuilder.cpp +++ b/src/engine/assets/model/builders/SceneBuilder.cpp @@ -277,11 +277,9 @@ namespace fgl::engine return textures; } - std::vector< GameObject > SceneBuilder::getGameObjects() + std::vector< std::shared_ptr< GameObject > > SceneBuilder::getGameObjects() { - std::vector< GameObject > objects { std::move( this->game_objects ) }; - - return objects; + return this->m_game_objects; } std::vector< glm::vec3 > SceneBuilder:: @@ -592,7 +590,7 @@ namespace fgl::engine const int mesh_idx { node.mesh }; const int skin_idx { node.skin }; - GameObject obj { GameObject::createGameObject() }; + auto obj { GameObject::createGameObject() }; std::shared_ptr< Model > model { loadModel( mesh_idx, root ) }; @@ -605,18 +603,18 @@ namespace fgl::engine const auto transform { loadTransform( node_idx, root ) }; // component->updateTransform( transform ); - obj.addComponent( std::move( component ) ); + obj->addComponent( std::move( component ) ); - obj.addFlag( IsVisible | IsEntity ); + obj->addFlag( IsVisible | IsEntity ); // obj.getTransform() = transform; if ( node.name.empty() ) - obj.setName( "Unnamed Game Object" ); + obj->setName( "Unnamed Game Object" ); else - obj.setName( node.name ); + obj->setName( node.name ); - this->game_objects.emplace_back( std::move( obj ) ); + this->m_game_objects.emplace_back( std::move( obj ) ); } void SceneBuilder::handleScene( const tinygltf::Scene& scene, const tinygltf::Model& root ) diff --git a/src/engine/assets/model/builders/SceneBuilder.hpp b/src/engine/assets/model/builders/SceneBuilder.hpp index 35a2287..0397fe0 100644 --- a/src/engine/assets/model/builders/SceneBuilder.hpp +++ b/src/engine/assets/model/builders/SceneBuilder.hpp @@ -53,7 +53,7 @@ namespace fgl::engine memory::Buffer m_vertex_buffer; memory::Buffer m_index_buffer; - std::vector< GameObject > game_objects {}; + std::vector< std::shared_ptr< GameObject > > m_game_objects {}; void handleScene( const tinygltf::Scene& scene, const tinygltf::Model& root ); void handleNode( int node_idx, const tinygltf::Model& root ); @@ -88,7 +88,7 @@ namespace fgl::engine public: - std::vector< GameObject > getGameObjects(); + std::vector< std::shared_ptr< GameObject > > getGameObjects(); SceneBuilder() = delete; diff --git a/src/engine/assets/transfer/TransferData.cpp b/src/engine/assets/transfer/TransferData.cpp index a686b89..761e113 100644 --- a/src/engine/assets/transfer/TransferData.cpp +++ b/src/engine/assets/transfer/TransferData.cpp @@ -61,7 +61,7 @@ namespace fgl::engine::memory barriers_to ); vk::BufferImageCopy region {}; - region.bufferOffset = source_buffer->getOffset(); + region.bufferOffset = source_buffer->offset(); region.bufferRowLength = 0; region.bufferImageHeight = 0; @@ -178,7 +178,7 @@ namespace fgl::engine::memory } case eImageFromBuffer: { - if ( !std::get< TransferBufferHandle >( m_source )->transferReady() ) return false; + if ( !std::get< TransferBufferHandle >( m_source )->stable() ) return false; return performImageStage( buffer, transfer_idx, graphics_idx ); } case eBufferFromRaw: @@ -187,7 +187,7 @@ namespace fgl::engine::memory } case eBufferFromBuffer: { - if ( !std::get< TransferBufferHandle >( m_source )->transferReady() ) return false; + if ( !std::get< TransferBufferHandle >( m_source )->stable() ) return false; return performBufferStage( copy_regions ); } } @@ -241,9 +241,9 @@ namespace fgl::engine::memory m_source_offset( src_offset ), m_target( target ), m_target_offset( dst_offset ), - m_size( size == 0 ? source->m_size : size ) + m_size( size == 0 ? source->size() : size ) { - FGL_ASSERT( m_size <= target->m_size, "Attempting to copy to beyond size of target" ); + FGL_ASSERT( m_size <= target->size(), "Attempting to copy to beyond size of target" ); markBad(); } @@ -261,7 +261,7 @@ namespace fgl::engine::memory m_target_offset( dst_offset ), m_size( size == 0 ? source.size() : size ) { - FGL_ASSERT( m_size <= target->m_size, "Attempting to copy to beyond size of target" ); + FGL_ASSERT( m_size <= target->size(), "Attempting to copy to beyond size of target" ); markBad(); } @@ -276,7 +276,7 @@ namespace fgl::engine::memory m_source_offset( src_offset ), m_target( target ), m_target_offset( 0 ), - m_size( size == 0 ? source->m_size : size ) + m_size( size == 0 ? source->size() : size ) { markBad(); } diff --git a/src/engine/assets/transfer/TransferManager.cpp b/src/engine/assets/transfer/TransferManager.cpp index 4f96578..f621cfe 100644 --- a/src/engine/assets/transfer/TransferManager.cpp +++ b/src/engine/assets/transfer/TransferManager.cpp @@ -99,6 +99,24 @@ namespace fgl::engine::memory m_staging_buffer.resize( size ); } + void TransferManager::copySuballocationRegion( + const std::shared_ptr< BufferSuballocationHandle >& src, + const std::shared_ptr< BufferSuballocationHandle >& dst, + const vk::DeviceSize size, + const vk::DeviceSize dst_offset, + const std::size_t src_offset ) + { + FGL_ASSERT( src->size() == dst->size(), "Source and destination suballocations must be the same size" ); + + //! If the buffer has not been staged, Then there is nothing to copy in the first place. + //! If the source is not stable, Then it might be staged in the future. + if ( !src->ready() ) return; + + TransferData transfer_data { src, dst, size, dst_offset, src_offset }; + + m_queue.emplace( std::move( transfer_data ) ); + } + void TransferManager::submitBuffer( const vk::raii::CommandBuffer& command_buffer ) const { ZoneScoped; diff --git a/src/engine/assets/transfer/TransferManager.hpp b/src/engine/assets/transfer/TransferManager.hpp index 5f9ecca..387a031 100644 --- a/src/engine/assets/transfer/TransferManager.hpp +++ b/src/engine/assets/transfer/TransferManager.hpp @@ -104,22 +104,9 @@ namespace fgl::engine::memory void copySuballocationRegion( const std::shared_ptr< BufferSuballocationHandle >& src, const std::shared_ptr< BufferSuballocationHandle >& dst, - const vk::DeviceSize size = 0, - const vk::DeviceSize dst_offset = 0, - const std::size_t src_offset = 0 ) - { - FGL_ASSERT( src->m_size == dst->m_size, "Source and destination suballocations must be the same size" ); - - //! If the buffer has not been staged, Then there is nothing to copy in the first place. - if ( !src->m_staged ) return; - - // Makes the dst as requiring the src to be stable (no pending writes) before it's used. - dst->markRequiresStable( src ); - - TransferData transfer_data { src, dst, size, dst_offset, src_offset }; - - m_queue.emplace( std::move( transfer_data ) ); - } + vk::DeviceSize size = 0, + vk::DeviceSize dst_offset = 0, + std::size_t src_offset = 0 ); //! Queues a buffer to be transfered template < typename DeviceVectorT > diff --git a/src/engine/gameobjects/GameObject.cpp b/src/engine/gameobjects/GameObject.cpp index 27c7b7b..8ba4f04 100644 --- a/src/engine/gameobjects/GameObject.cpp +++ b/src/engine/gameobjects/GameObject.cpp @@ -37,10 +37,10 @@ namespace fgl::engine other.m_id = INVALID_ID; } - GameObject GameObject::createGameObject() + std::shared_ptr< GameObject > GameObject::createGameObject() { static GameObjectID current_id { 0 }; - return GameObject( current_id++ ); + return std::shared_ptr< GameObject >( new GameObject( current_id++ ) ); } } // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/gameobjects/GameObject.hpp b/src/engine/gameobjects/GameObject.hpp index c5c3d9c..bd2008f 100644 --- a/src/engine/gameobjects/GameObject.hpp +++ b/src/engine/gameobjects/GameObject.hpp @@ -127,7 +127,7 @@ namespace fgl::engine void removeFlag( GameObjectFlagType flag ) { object_flags &= ( ~flag ); } //Misc - static GameObject createGameObject(); + static std::shared_ptr< GameObject > createGameObject(); GameObjectID getId() const { return m_id; } diff --git a/src/engine/memory/buffers/BufferHandle.cpp b/src/engine/memory/buffers/BufferHandle.cpp index c7df3fc..11c259f 100644 --- a/src/engine/memory/buffers/BufferHandle.cpp +++ b/src/engine/memory/buffers/BufferHandle.cpp @@ -62,8 +62,8 @@ namespace fgl::engine::memory { if ( suballocation.expired() ) continue; auto suballoc_ptr { suballocation.lock() }; - const auto offset { suballoc_ptr->m_offset }; - const auto size { suballoc_ptr->m_size }; + const auto offset { suballoc_ptr->offset() }; + const auto size { suballoc_ptr->size() }; log::info( "Stacktrace: Offset at {} with a size of {}", offset, size ); const auto itter = this->m_allocation_traces.find( offset ); @@ -87,10 +87,10 @@ namespace fgl::engine::memory { if ( m_alloc_info.pMappedData == nullptr ) return nullptr; - return static_cast< std::byte* >( m_alloc_info.pMappedData ) + handle.m_offset; + return static_cast< std::byte* >( m_alloc_info.pMappedData ) + handle.offset(); } - void BufferHandle::deallocBuffer( vk::Buffer& buffer, VmaAllocation& allocation ) + void BufferHandle::deallocBuffer( const vk::Buffer& buffer, const VmaAllocation& allocation ) { vmaDestroyBuffer( Device::getInstance().allocator(), buffer, allocation ); } @@ -235,14 +235,14 @@ namespace fgl::engine::memory auto suballocation { suballocation_weak.lock() }; - if ( auto new_suballocation { new_handle->allocate( suballocation->m_size, suballocation->m_alignment ) } ) - { - allocations.emplace_back( suballocation, new_suballocation ); - // Copy the data from the old allocation to the new allocation - TransferManager::getInstance().copySuballocationRegion( suballocation, new_suballocation ); - } - else - throw std::runtime_error( "The fuck" ); + auto [ old_suballocation, new_suballocation ] = suballocation->reallocate( new_handle ); + + allocations.emplace_back( old_suballocation, new_suballocation ); + + // Copy the data from the old allocation to the new allocation + TransferManager::getInstance().copySuballocationRegion( old_suballocation, new_suballocation ); + + old_suballocation->flagReallocated( new_suballocation ); } return new_handle; @@ -453,18 +453,18 @@ namespace fgl::engine::memory { ZoneScoped; - 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() ) + if ( info.offset() >= this->size() ) throw std::runtime_error( "Offset was outside of bounds of buffer" ); + if ( info.offset() + info.size() > this->size() ) throw std::runtime_error( std::format( - "m_offset + m_size was outside the bounds of the buffer ({} + {} == {} >= {})", - info.m_offset, - info.m_size, - info.m_offset + info.m_size, + "offset() + size() was outside the bounds of the buffer ({} + {} == {} >= {})", + info.offset(), + info.size(), + info.offset() + info.size(), size() ) ); //Add the block back to the free blocks - m_free_blocks.emplace_back( info.m_offset, info.m_size ); + m_free_blocks.emplace_back( info.offset(), info.size() ); mergeFreeBlocks(); @@ -479,7 +479,7 @@ namespace fgl::engine::memory for ( auto& suballocation : m_active_suballocations ) { if ( suballocation.expired() ) continue; - sum += suballocation.lock()->m_size; + sum += suballocation.lock()->size(); } if ( sum != this->size() ) @@ -495,7 +495,7 @@ namespace fgl::engine::memory for ( auto& suballocation : m_active_suballocations ) { if ( suballocation.expired() ) continue; - total_size += suballocation.lock()->m_size; + total_size += suballocation.lock()->size(); } return total_size; diff --git a/src/engine/memory/buffers/BufferHandle.hpp b/src/engine/memory/buffers/BufferHandle.hpp index e4618b7..ad3890b 100644 --- a/src/engine/memory/buffers/BufferHandle.hpp +++ b/src/engine/memory/buffers/BufferHandle.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -17,6 +16,7 @@ #include "FGL_DEFINES.hpp" #include "engine/debug/Track.hpp" +#include "math/literals/size.hpp" #include "vma/vma_impl.hpp" namespace fgl::engine @@ -33,7 +33,7 @@ namespace fgl::engine namespace fgl::engine::memory { class BufferSuballocation; - struct BufferSuballocationHandle; + class BufferSuballocationHandle; enum AllocationStatus : std::uint8_t { @@ -79,7 +79,7 @@ namespace fgl::engine::memory static std::tuple< vk::Buffer, VmaAllocationInfo, VmaAllocation > allocBuffer( vk::DeviceSize memory_size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags property_flags ); - static void deallocBuffer( vk::Buffer&, VmaAllocation& ); + static void deallocBuffer( const vk::Buffer&, const VmaAllocation& ); BufferHandle() = delete; BufferHandle( const BufferHandle& other ) = delete; @@ -117,6 +117,11 @@ namespace fgl::engine::memory return m_alloc_info.deviceMemory; } + FGL_FORCE_INLINE std::string sizeName() const + { + return std::format( "{}: {}", m_debug_name, literals::size_literals::toString( size() ) ); + } + friend struct BufferSuballocationHandle; friend class BufferSuballocation; //TODO: Remove this @@ -126,7 +131,7 @@ namespace fgl::engine::memory private: - friend struct Buffer; + friend class Buffer; std::shared_ptr< BufferHandle > remake( vk::DeviceSize new_size ); // void resize( vk::DeviceSize new_size ); @@ -168,17 +173,28 @@ namespace fgl::engine::memory decltype( m_free_blocks )::iterator findAvailableBlock( vk::DeviceSize memory_size, std::uint32_t t_alignment ); }; - struct Buffer final : public std::shared_ptr< BufferHandle > + class Buffer final : public std::shared_ptr< BufferHandle > { - Buffer( vk::DeviceSize memory_size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags memory_properties ) : + Buffer operator=( const std::shared_ptr< BufferHandle >& other ) + { + std::shared_ptr< BufferHandle >::operator=( other ); + return *this; + } + + public: + + [[nodiscard]] Buffer( + vk::DeviceSize memory_size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags memory_properties ) : std::shared_ptr< BufferHandle >( std::make_shared< BufferHandle >( memory_size, usage, memory_properties ) ) {} - Buffer( const std::shared_ptr< BufferHandle >& buffer ) : std::shared_ptr< BufferHandle >( buffer ) {} + [[nodiscard]] explicit Buffer( const std::shared_ptr< BufferHandle >& buffer ) : + std::shared_ptr< BufferHandle >( buffer ) + {} BufferSuballocation allocate( vk::DeviceSize desired_size, std::uint32_t alignment = 1 ); - vk::DeviceSize size() const { return std::shared_ptr< BufferHandle >::operator->()->size(); } + [[nodiscard]] vk::DeviceSize size() const { return std::shared_ptr< BufferHandle >::operator->()->size(); } void resize( vk::DeviceSize size ); diff --git a/src/engine/memory/buffers/BufferSuballocationHandle.cpp b/src/engine/memory/buffers/BufferSuballocationHandle.cpp index 0a5ac53..be170e0 100644 --- a/src/engine/memory/buffers/BufferSuballocationHandle.cpp +++ b/src/engine/memory/buffers/BufferSuballocationHandle.cpp @@ -45,8 +45,8 @@ namespace fgl::engine::memory { vk::BufferCopy copy {}; copy.size = std::min( this->m_size, target.m_size ); - copy.srcOffset = this->getOffset(); - copy.dstOffset = target.getOffset() + suballocation_offset; + copy.srcOffset = this->offset(); + copy.dstOffset = target.offset() + suballocation_offset; return copy; } @@ -62,4 +62,34 @@ namespace fgl::engine::memory cmd_buffer.copyBuffer( this->getVkBuffer(), other.getVkBuffer(), copy_regions ); } + std::pair< std::shared_ptr< BufferSuballocationHandle >, std::shared_ptr< BufferSuballocationHandle > > + BufferSuballocationHandle::reallocate( const std::shared_ptr< BufferHandle >& shared ) + { + auto old_allocation { this->shared_from_this() }; + auto new_allocation { shared->allocate( m_size, m_alignment ) }; + + return { old_allocation, new_allocation }; + } + + void BufferSuballocationHandle::markSource( const std::shared_ptr< BufferSuballocationHandle >& source ) + { + m_dependents.push_back( source ); + } + + bool BufferSuballocationHandle::stable() const + { + return std::ranges:: + all_of( m_dependents, []( const auto& handle ) { return handle.expired() || handle.lock()->ready(); } ); + } + + bool BufferSuballocationHandle::ready() const + { + return m_staged; + } + + void BufferSuballocationHandle::setReady( const bool value ) + { + std::ranges::remove_if( m_dependents, []( const auto& handle ) { return handle.expired(); } ); + m_staged = value; + } } // namespace fgl::engine::memory \ No newline at end of file diff --git a/src/engine/memory/buffers/BufferSuballocationHandle.hpp b/src/engine/memory/buffers/BufferSuballocationHandle.hpp index 639efac..4a8693b 100644 --- a/src/engine/memory/buffers/BufferSuballocationHandle.hpp +++ b/src/engine/memory/buffers/BufferSuballocationHandle.hpp @@ -20,8 +20,10 @@ namespace fgl::engine::memory { class BufferHandle; - struct BufferSuballocationHandle : public std::enable_shared_from_this< BufferSuballocationHandle > + class BufferSuballocationHandle : public std::enable_shared_from_this< BufferSuballocationHandle > { + friend class BufferSuballocation; + Buffer m_parent_buffer; debug::Track< "GPU", "BufferSuballocationHandle" > m_track {}; @@ -37,10 +39,13 @@ namespace fgl::engine::memory void* m_ptr { nullptr }; - bool m_staged { false }; + bool m_reallocated { false }; + std::shared_ptr< BufferSuballocationHandle > m_reallocated_to { nullptr }; - //! A list of all sources that are wanting to write to this buffer. - std::queue< std::shared_ptr< BufferSuballocationHandle > > m_pending_sources {}; + bool m_staged { false }; + std::vector< std::weak_ptr< BufferSuballocationHandle > > m_dependents {}; + + public: BufferSuballocationHandle( const Buffer& p_buffer, vk::DeviceSize offset, vk::DeviceSize memory_size, vk::DeviceSize alignment ); @@ -51,32 +56,44 @@ namespace fgl::engine::memory ~BufferSuballocationHandle(); - [[nodiscard]] vk::Buffer getBuffer() const; - [[nodiscard]] vk::Buffer getVkBuffer() const; - - [[nodiscard]] vk::BufferCopy - copyRegion( const BufferSuballocationHandle& target, std::size_t suballocation_offset ) const; - void copyTo( const vk::raii::CommandBuffer& cmd_buffer, const BufferSuballocationHandle& other, std::size_t offset ) const; - void markRequiresStable( const std::shared_ptr< BufferSuballocationHandle >& src ) + void flagReallocated( const std::shared_ptr< BufferSuballocationHandle >& shared ) { - m_pending_sources.push( src ); + m_reallocated = true; + m_reallocated_to = shared; } - //! Returns true if this data is stable (No pending writes) - bool stable() const { return m_pending_sources.empty(); } + std::pair< std::shared_ptr< BufferSuballocationHandle >, std::shared_ptr< BufferSuballocationHandle > > + reallocate( const std::shared_ptr< BufferHandle >& shared ); - [[nodiscard]] vk::DeviceSize getOffset() const { return m_offset; } + bool reallocated() const { return m_reallocated; } - bool transferReady() const { return m_staged && m_pending_sources.empty(); } + std::shared_ptr< BufferSuballocationHandle > reallocatedTo() const { return m_reallocated_to; } - bool ready() const { return m_staged && m_pending_sources.empty(); } + void markSource( const std::shared_ptr< BufferSuballocationHandle >& source ); - void setReady( const bool value ) { m_staged = value; } + void setReady( bool value ); + + [[nodiscard]] vk::BufferCopy + copyRegion( const BufferSuballocationHandle& target, std::size_t suballocation_offset ) const; + + [[nodiscard]] vk::Buffer getBuffer() const; + [[nodiscard]] vk::Buffer getVkBuffer() const; + + vk::DeviceSize offset() const { return m_offset; } + + //! True if there are no pending writes + bool stable() const; + //! True if the data in the buffer is valid (Written to at least once) + bool ready() const; + + vk::DeviceSize size() const { return m_size; } + + vk::DeviceSize alignment() const { return m_alignment; } }; } // namespace fgl::engine::memory diff --git a/src/engine/memory/buffers/SuballocationView.cpp b/src/engine/memory/buffers/SuballocationView.cpp index 1ebd65b..6304a87 100644 --- a/src/engine/memory/buffers/SuballocationView.cpp +++ b/src/engine/memory/buffers/SuballocationView.cpp @@ -15,9 +15,9 @@ namespace fgl::engine::memory return m_suballocation->getVkBuffer(); } - vk::DeviceSize SuballocationView::getOffset() + vk::DeviceSize SuballocationView::offset() { - return m_offset + m_suballocation->getOffset(); + return m_offset + m_suballocation->offset(); } void SuballocationView::setOffset( vk::DeviceSize offset ) diff --git a/src/engine/memory/buffers/SuballocationView.hpp b/src/engine/memory/buffers/SuballocationView.hpp index 6d63118..1b0a0a6 100644 --- a/src/engine/memory/buffers/SuballocationView.hpp +++ b/src/engine/memory/buffers/SuballocationView.hpp @@ -34,7 +34,7 @@ namespace fgl::engine::memory vk::Buffer getVkBuffer(); //! Returns the offset of this view within the buffer - vk::DeviceSize getOffset(); + vk::DeviceSize offset(); }; } // namespace fgl::engine::memory \ No newline at end of file