Cleanup more transfer buffer things
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <imgui_internal.h> // 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();
|
||||
}
|
||||
|
||||
@@ -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 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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() };
|
||||
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 ) );
|
||||
}
|
||||
|
||||
@@ -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 = {} );
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 >
|
||||
|
||||
@@ -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
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <stacktrace>
|
||||
#include <unordered_map>
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user