From fb698e36346509170f1893d71a82d38dea3b4728 Mon Sep 17 00:00:00 2001 From: Egor Orachyov Date: Sun, 20 Oct 2024 15:49:16 +0300 Subject: [PATCH] gh-81: mesh manager for gpu mesh data --- engine/plugins/assimp/assimp_asset_loader.cpp | 19 ++- engine/runtime/core/string_id.cpp | 17 ++- engine/runtime/core/string_id.hpp | 10 ++ engine/runtime/gfx/vulkan/vk_cmd_manager.cpp | 3 + engine/runtime/grc/texture_manager.cpp | 5 +- engine/runtime/grc/texture_manager.hpp | 5 +- engine/runtime/mesh/mesh.cpp | 59 +++++---- engine/runtime/mesh/mesh.hpp | 53 ++++---- engine/runtime/mesh/mesh_builder.cpp | 20 +-- engine/runtime/mesh/mesh_builder.hpp | 5 +- engine/runtime/mesh/mesh_manager.cpp | 125 +++++++++++++++--- engine/runtime/mesh/mesh_manager.hpp | 26 ++-- engine/runtime/system/engine.cpp | 1 + template/main.cpp | 2 +- 14 files changed, 232 insertions(+), 118 deletions(-) diff --git a/engine/plugins/assimp/assimp_asset_loader.cpp b/engine/plugins/assimp/assimp_asset_loader.cpp index 838d25f31..a9babb7bd 100644 --- a/engine/plugins/assimp/assimp_asset_loader.cpp +++ b/engine/plugins/assimp/assimp_asset_loader.cpp @@ -76,22 +76,21 @@ namespace wmoge { return StatusCode::Error; } - MeshManager* mesh_manager = context.ioc->resolve_value(); - - MeshFlags flags; - flags.set(MeshFlag::FromDisk); - - asset = mesh_manager->create_mesh(flags); - asset->set_id(asset_id); - MeshBuilder& builder = importer.get_builder(); - builder.set_mesh(asset); if (!builder.build()) { WG_LOG_ERROR("failed to build mesh " << asset_id); return StatusCode::Error; } - mesh_manager->init_mesh(asset.get()); + MeshDesc& desc = builder.get_mesh(); + desc.flags.set(MeshFlag::FromDisk); + + MeshManager* mesh_manager = context.ioc->resolve_value(); + + asset = mesh_manager->create_mesh(desc); + asset->set_id(asset_id); + + mesh_manager->queue_mesh_upload(asset.get()); return WG_OK; } diff --git a/engine/runtime/core/string_id.cpp b/engine/runtime/core/string_id.cpp index da5643ef8..4769ab14a 100644 --- a/engine/runtime/core/string_id.cpp +++ b/engine/runtime/core/string_id.cpp @@ -43,7 +43,7 @@ namespace wmoge { class StringStorage { public: void get_or_create(const std::string& key, const std::string*& str); - static StringStorage& instance(); + static StringStorage& instance(StridPool pool); private: struct Entry { @@ -69,9 +69,9 @@ namespace wmoge { str = &entry->str; } - StringStorage& StringStorage::instance() { - static StringStorage g_storage; - return g_storage; + StringStorage& StringStorage::instance(StridPool pool) { + static StringStorage g_storage[static_cast(StridPool::Max)]; + return g_storage[static_cast(pool)]; } Strid::Strid() { @@ -79,12 +79,15 @@ namespace wmoge { m_string = &g_empty; } - Strid::Strid(const char* string) : Strid(std::string(string)) { + Strid::Strid(const char* string) : Strid(std::string(string), StridPool::Release) { } - Strid::Strid(const std::string& string) : Strid() { + Strid::Strid(const std::string& string) : Strid(string, StridPool::Release) { + } + + Strid::Strid(const std::string& string, StridPool pool) { if (string.empty()) return; - StringStorage::instance().get_or_create(string, m_string); + StringStorage::instance(pool).get_or_create(string, m_string); } bool Strid::operator==(const Strid& other) const { diff --git a/engine/runtime/core/string_id.hpp b/engine/runtime/core/string_id.hpp index 504d52b20..8bb6889b9 100644 --- a/engine/runtime/core/string_id.hpp +++ b/engine/runtime/core/string_id.hpp @@ -35,6 +35,13 @@ namespace wmoge { + /** @brief Pool to allocate strid, separated for profiling purposes */ + enum class StridPool { + Release = 0, + Debug, + Max + }; + /** * @class Strid * @brief Interned globally-stored string based ids for fast lookups @@ -44,6 +51,7 @@ namespace wmoge { Strid(); Strid(const char* string); Strid(const std::string& string); + Strid(const std::string& string, StridPool pool); bool operator==(const Strid& other) const; bool operator!=(const Strid& other) const; @@ -68,6 +76,8 @@ namespace wmoge { #define SID(id) ::wmoge::Strid(id) +#define SIDDBG(id) ::wmoge::Strid(id, ::wmoge::StridPool::Debug) + }// namespace wmoge namespace std { diff --git a/engine/runtime/gfx/vulkan/vk_cmd_manager.cpp b/engine/runtime/gfx/vulkan/vk_cmd_manager.cpp index 01cb32755..00d991df0 100644 --- a/engine/runtime/gfx/vulkan/vk_cmd_manager.cpp +++ b/engine/runtime/gfx/vulkan/vk_cmd_manager.cpp @@ -185,11 +185,14 @@ namespace wmoge { buffered_vector wait_flags; for (CmdBufferQueue& queue : m_queues) { + WG_PROFILE_CPU_VULKAN("submit_queue"); std::size_t num_commands = queue.submits.size(); const bool is_graphics_queue = queue.queue_type == GfxQueueType::Graphics; for (std::size_t i = 0; i < num_commands; i++) { + WG_PROFILE_CPU_VULKAN("submit_cmd_buffer"); + CmdBufferSubmitInfo& submit = queue.submits[i]; if (is_graphics_queue) { diff --git a/engine/runtime/grc/texture_manager.cpp b/engine/runtime/grc/texture_manager.cpp index 8e79338ac..84f78b274 100644 --- a/engine/runtime/grc/texture_manager.cpp +++ b/engine/runtime/grc/texture_manager.cpp @@ -277,9 +277,9 @@ namespace wmoge { const GfxTextureDesc desc = texture->get_desc(); if (is_pooled) { - texture->set_texture(m_pool->allocate(desc, texture->get_name())); + texture->set_texture(m_pool->allocate(desc, SIDDBG(texture->get_name().str()))); } else { - texture->set_texture(m_gfx_driver->make_texture(desc, texture->get_name())); + texture->set_texture(m_gfx_driver->make_texture(desc, SIDDBG(texture->get_name().str()))); } texture->set_texture_callback(m_callback); @@ -298,6 +298,7 @@ namespace wmoge { } void TextureManager::upload_texture(Texture* texture, const GfxCmdListRef& cmd) { + WG_PROFILE_CPU_GRC("TextureManager::upload_texture"); WG_PROFILE_GPU_SCOPE(cmd, "TextureManager::upload_texture"); assert(texture); diff --git a/engine/runtime/grc/texture_manager.hpp b/engine/runtime/grc/texture_manager.hpp index db651b83e..614d54bd2 100644 --- a/engine/runtime/grc/texture_manager.hpp +++ b/engine/runtime/grc/texture_manager.hpp @@ -102,9 +102,8 @@ namespace wmoge { Texture::CallbackRef m_callback; std::unique_ptr m_pool; bool m_need_upload_default = true; - - Ref m_default_textures[int(DefaultTexture::Total)]; - Ref m_default_samplers[int(DefaultSampler::Total)]; + Ref m_default_textures[int(DefaultTexture::Total)]; + Ref m_default_samplers[int(DefaultSampler::Total)]; GfxDriver* m_gfx_driver; diff --git a/engine/runtime/mesh/mesh.cpp b/engine/runtime/mesh/mesh.cpp index 6601bab43..e0631c7e4 100644 --- a/engine/runtime/mesh/mesh.cpp +++ b/engine/runtime/mesh/mesh.cpp @@ -33,29 +33,23 @@ namespace wmoge { - Mesh::Mesh(MeshFlags flags) { - m_flags = flags; + Mesh::~Mesh() { + if (m_callback) { + (*m_callback)(this); + } } - void Mesh::add_chunk(const MeshChunk& mesh_chunk, const Ref& mesh) { - m_chunks.push_back(mesh_chunk); - m_array_meshes.push_back(mesh); - } - void Mesh::add_vertex_buffer(Ref buffer) { - m_vertex_buffers.push_back(std::move(buffer)); - } - void Mesh::add_index_buffer(Ref buffer) { - m_index_buffers.push_back(std::move(buffer)); - } - void Mesh::add_vert_stream(const MeshVertStream& stream) { - m_vert_streams.push_back(stream); - } - void Mesh::add_intex_stream(const MeshIndexStream& stream) { - m_index_streams.push_back(stream); - } - void Mesh::set_aabb(const Aabbf& aabb) { - m_aabb = aabb; + Mesh::Mesh(MeshDesc& mesh_desc) { + m_chunks = std::move(mesh_desc.chunks); + m_array_meshes = std::move(mesh_desc.array_meshes); + m_vertex_buffers = std::move(mesh_desc.vertex_buffers); + m_index_buffers = std::move(mesh_desc.index_buffers); + m_vert_streams = std::move(mesh_desc.vert_streams); + m_index_streams = std::move(mesh_desc.index_streams); + m_aabb = mesh_desc.aabb; + m_flags = mesh_desc.flags; } + void Mesh::set_mesh_callback(CallbackRef callback) { m_callback = std::move(callback); } @@ -66,6 +60,11 @@ namespace wmoge { m_gfx_index_buffers = std::move(gfx_index_buffers); } + void Mesh::release_gfx_buffers() { + m_gfx_vertex_buffers.clear(); + m_gfx_index_buffers.clear(); + } + GfxVertBuffersSetup Mesh::get_vert_buffers_setup(int chunk_id) const { GfxVertBuffersSetup setup; const MeshChunk& chunk = get_chunk(chunk_id); @@ -94,23 +93,35 @@ namespace wmoge { array_view> Mesh::get_array_meshes() const { return m_array_meshes; } + array_view> Mesh::get_vertex_buffers() const { + return m_vertex_buffers; + } + array_view> Mesh::get_index_buffers() const { + return m_index_buffers; + } + array_view> Mesh::get_gfx_vertex_buffers() const { + return m_gfx_vertex_buffers; + } + array_view> Mesh::get_gfx_index_buffers() const { + return m_gfx_index_buffers; + } const MeshChunk& Mesh::get_chunk(int i) const { assert(i < m_chunks.size()); return m_chunks[i]; } - const Ref& Mesh::get_gfx_vertex_buffers(int i) const { + const Ref& Mesh::get_gfx_vertex_buffer(int i) const { assert(i < m_gfx_vertex_buffers.size()); return m_gfx_vertex_buffers[i]; } - const Ref& Mesh::get_gfx_index_buffers(int i) const { + const Ref& Mesh::get_gfx_index_buffer(int i) const { assert(i < m_gfx_vertex_buffers.size()); return m_gfx_index_buffers[i]; } - const MeshVertStream& Mesh::get_vert_streams(int i) const { + const MeshVertStream& Mesh::get_vert_stream(int i) const { assert(i < m_gfx_vertex_buffers.size()); return m_vert_streams[i]; } - const MeshIndexStream& Mesh::get_index_streams(int i) const { + const MeshIndexStream& Mesh::get_index_stream(int i) const { assert(i < m_gfx_vertex_buffers.size()); return m_index_streams[i]; } diff --git a/engine/runtime/mesh/mesh.hpp b/engine/runtime/mesh/mesh.hpp index caf10790a..dc3549032 100644 --- a/engine/runtime/mesh/mesh.hpp +++ b/engine/runtime/mesh/mesh.hpp @@ -87,11 +87,11 @@ namespace wmoge { WG_RTTI_END; /** - * @class MeshData + * @class MeshDesc * @brief Struct used to serialize mesh asset data */ - struct MeshData { - WG_RTTI_STRUCT(MeshData); + struct MeshDesc { + WG_RTTI_STRUCT(MeshDesc); std::vector chunks; std::vector> array_meshes; @@ -100,9 +100,10 @@ namespace wmoge { std::vector vert_streams; std::vector index_streams; Aabbf aabb; + MeshFlags flags; }; - WG_RTTI_STRUCT_BEGIN(MeshData) { + WG_RTTI_STRUCT_BEGIN(MeshDesc) { WG_RTTI_META_DATA(); WG_RTTI_FIELD(chunks, {}); WG_RTTI_FIELD(array_meshes, {}); @@ -111,6 +112,7 @@ namespace wmoge { WG_RTTI_FIELD(vert_streams, {}); WG_RTTI_FIELD(index_streams, {}); WG_RTTI_FIELD(aabb, {}); + WG_RTTI_FIELD(flags, {}); } WG_RTTI_END; @@ -125,33 +127,32 @@ namespace wmoge { using Callback = std::function; using CallbackRef = std::shared_ptr; - Mesh() = default; - ~Mesh() override = default; + Mesh() = default; + ~Mesh() override; - Mesh(MeshFlags flags); + Mesh(MeshDesc& mesh_desc); - void add_chunk(const MeshChunk& mesh_chunk, const Ref& mesh); - void add_vertex_buffer(Ref buffer); - void add_index_buffer(Ref buffer); - void add_vert_stream(const MeshVertStream& stream); - void add_intex_stream(const MeshIndexStream& stream); - void set_aabb(const Aabbf& aabb); void set_mesh_callback(CallbackRef callback); void set_gfx_vertex_buffers(std::vector> gfx_vertex_buffers); void set_gfx_index_buffers(std::vector> gfx_index_buffers); - - [[nodiscard]] GfxVertBuffersSetup get_vert_buffers_setup(int chunk_id) const; - [[nodiscard]] GfxIndexBufferSetup get_index_buffer_setup(int chunk_id) const; - [[nodiscard]] array_view get_chunks() const; - [[nodiscard]] array_view> get_array_meshes() const; - [[nodiscard]] const MeshChunk& get_chunk(int i) const; - [[nodiscard]] const Ref& get_gfx_vertex_buffers(int i) const; - [[nodiscard]] const Ref& get_gfx_index_buffers(int i) const; - [[nodiscard]] const MeshVertStream& get_vert_streams(int i) const; - [[nodiscard]] const MeshIndexStream& get_index_streams(int i) const; - [[nodiscard]] const Aabbf& get_aabb() const; - [[nodiscard]] const MeshFlags& get_flags() const; - [[nodiscard]] GfxMemUsage get_mem_usage() const; + void release_gfx_buffers(); + + [[nodiscard]] GfxVertBuffersSetup get_vert_buffers_setup(int chunk_id) const; + [[nodiscard]] GfxIndexBufferSetup get_index_buffer_setup(int chunk_id) const; + [[nodiscard]] array_view get_chunks() const; + [[nodiscard]] array_view> get_array_meshes() const; + [[nodiscard]] array_view> get_vertex_buffers() const; + [[nodiscard]] array_view> get_index_buffers() const; + [[nodiscard]] array_view> get_gfx_vertex_buffers() const; + [[nodiscard]] array_view> get_gfx_index_buffers() const; + [[nodiscard]] const MeshChunk& get_chunk(int i) const; + [[nodiscard]] const Ref& get_gfx_vertex_buffer(int i) const; + [[nodiscard]] const Ref& get_gfx_index_buffer(int i) const; + [[nodiscard]] const MeshVertStream& get_vert_stream(int i) const; + [[nodiscard]] const MeshIndexStream& get_index_stream(int i) const; + [[nodiscard]] const Aabbf& get_aabb() const; + [[nodiscard]] const MeshFlags& get_flags() const; + [[nodiscard]] GfxMemUsage get_mem_usage() const; private: std::vector m_chunks; diff --git a/engine/runtime/mesh/mesh_builder.cpp b/engine/runtime/mesh/mesh_builder.cpp index 02d4bbdd9..7d768d30c 100644 --- a/engine/runtime/mesh/mesh_builder.cpp +++ b/engine/runtime/mesh/mesh_builder.cpp @@ -36,10 +36,6 @@ namespace wmoge { - void MeshBuilder::set_mesh(Ref mesh) { - m_mesh = std::move(mesh); - } - void MeshBuilder::add_chunk(const Strid& name, const Ref& data) { assert(data); @@ -50,8 +46,6 @@ namespace wmoge { Status MeshBuilder::build() { WG_PROFILE_CPU_MESH("MeshBuilder::build"); - assert(m_mesh); - const GfxVertAttribs attribs_stream1 = {GfxVertAttrib::Pos3f, GfxVertAttrib::Pos2f, GfxVertAttrib::Norm3f, GfxVertAttrib::Tang3f}; const GfxVertAttribs attribs_stream2 = {GfxVertAttrib::BoneIds4i, GfxVertAttrib::BoneWeights4f}; const GfxVertAttribs attribs_stream3 = {GfxVertAttrib::Col04f, GfxVertAttrib::Col14f, GfxVertAttrib::Col24f, GfxVertAttrib::Col34f, GfxVertAttrib::Uv02f, GfxVertAttrib::Uv12f, GfxVertAttrib::Uv22f, GfxVertAttrib::Uv32f}; @@ -80,7 +74,6 @@ namespace wmoge { m_chunks[i]->pack_faces(index_data, index_stream); index_stream.buffer = curr_index_buffer; - m_mesh->add_intex_stream(index_stream); MeshChunk chunk; chunk.name = m_chunks_names[i]; @@ -94,14 +87,15 @@ namespace wmoge { aabb = aabb.join(chunk.aabb); - m_mesh->add_chunk(chunk, m_chunks[i]); - - m_mesh->add_vertex_buffer(vert_data); - m_mesh->add_index_buffer(index_data); + m_mesh.chunks.push_back(chunk); + m_mesh.array_meshes.push_back(m_chunks[i]); + m_mesh.vertex_buffers.push_back(vert_data); + m_mesh.index_buffers.push_back(index_data); for (auto& vert_stream : vert_streams) { - m_mesh->add_vert_stream(vert_stream); + m_mesh.vert_streams.push_back(vert_stream); } + m_mesh.index_streams.push_back(index_stream); curr_index_stream += 1; curr_vert_stream += int(vert_streams.size()); @@ -110,7 +104,7 @@ namespace wmoge { curr_index_buffer += 1; } - m_mesh->set_aabb(aabb); + m_mesh.aabb = aabb; return WG_OK; } diff --git a/engine/runtime/mesh/mesh_builder.hpp b/engine/runtime/mesh/mesh_builder.hpp index 4a81cd5ce..23e992111 100644 --- a/engine/runtime/mesh/mesh_builder.hpp +++ b/engine/runtime/mesh/mesh_builder.hpp @@ -44,17 +44,16 @@ namespace wmoge { */ class MeshBuilder { public: - void set_mesh(Ref mesh); void add_chunk(const Strid& name, const Ref& data); Status build(); - [[nodiscard]] const Ref& get_mesh() const { return m_mesh; } + [[nodiscard]] MeshDesc& get_mesh() { return m_mesh; } private: std::vector> m_chunks; std::vector m_chunks_names; - Ref m_mesh; + MeshDesc m_mesh; }; }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/mesh/mesh_manager.cpp b/engine/runtime/mesh/mesh_manager.cpp index 89a1bd272..24fe47c48 100644 --- a/engine/runtime/mesh/mesh_manager.cpp +++ b/engine/runtime/mesh/mesh_manager.cpp @@ -30,6 +30,7 @@ #include "core/ioc_container.hpp" #include "gfx/gfx_driver.hpp" #include "profiler/profiler_cpu.hpp" +#include "profiler/profiler_gpu.hpp" #include @@ -40,11 +41,13 @@ namespace wmoge { m_callback = std::make_shared([this](Mesh* mesh) { remove_mesh(mesh); }); } - Ref MeshManager::create_mesh(MeshFlags flags) { - flags.set(MeshFlag::Managed); + Ref MeshManager::create_mesh(MeshDesc& desc) { + WG_PROFILE_CPU_MESH("MeshManager::create_mesh"); + std::lock_guard guard(m_mutex); - Ref mesh = make_ref(flags); - add_mesh(mesh); + desc.flags |= {MeshFlag::Managed}; + auto mesh = make_ref(desc); + init_mesh(mesh.get()); return mesh; } @@ -53,6 +56,7 @@ namespace wmoge { assert(!has_mesh(mesh.get())); std::lock_guard guard(m_mutex); + mesh->set_mesh_callback(m_callback); m_meshes[mesh.get()].weak_ref = mesh; } @@ -64,35 +68,126 @@ namespace wmoge { std::lock_guard guard(m_mutex); auto entry = m_meshes.find(mesh); - if (entry->second.state.get(MeshState::Inited)) { - delete_gfx_resource(mesh); - } + delete_mesh(mesh); m_meshes.erase(entry); } - void MeshManager::init_mesh(Mesh* mesh) { + void MeshManager::queue_mesh_upload(Mesh* mesh) { assert(mesh); assert(has_mesh(mesh)); - create_gfx_resource(mesh); - std::lock_guard guard(m_mutex); - m_meshes[mesh].state.set(MeshState::Inited); - m_meshes[mesh].state.set(MeshState::PendingUpload); + m_meshes[mesh].state.set(State::PendingUpload); } bool MeshManager::has_mesh(Mesh* mesh) { + assert(mesh); + std::lock_guard guard(m_mutex); return m_meshes.find(mesh) != m_meshes.end(); } - void MeshManager::create_gfx_resource(Mesh* mesh) { + void MeshManager::flush_meshes_upload() { + WG_PROFILE_CPU_MESH("MeshManager::flush_meshes_upload"); + + std::lock_guard guard(m_mutex); + + std::vector for_upload; + for (auto& iter : m_meshes) { + auto& entry = iter.second; + + if (entry.state.get(State::PendingUpload)) { + entry.state.set(State::PendingUpload, false); + for_upload.push_back(iter.first); + } + } + + if (for_upload.empty()) { + return; + } + + std::vector for_barrier; + for (Mesh* mesh : for_upload) { + array_view> gfx_vb = mesh->get_gfx_vertex_buffers(); + for (auto& buffer : gfx_vb) { + for_barrier.push_back(buffer.get()); + } + + array_view> gfx_ib = mesh->get_gfx_index_buffers(); + for (auto& buffer : gfx_ib) { + for_barrier.push_back(buffer.get()); + } + } + + auto cmd = m_gfx_driver->acquire_cmd_list(GfxQueueType::Graphics); + WG_PROFILE_GPU_BEGIN(cmd); + { + WG_PROFILE_GPU_SCOPE(cmd, "MeshManager::flust_meshes_upload"); + + cmd->barrier_buffers(for_barrier); + for (Mesh* mesh : for_upload) { + upload_mesh(mesh, cmd); + } + cmd->barrier_buffers(for_barrier); + } + WG_PROFILE_GPU_END(cmd); + m_gfx_driver->submit_cmd_list(cmd); + + WG_LOG_INFO("uploaded " << for_upload.size() << " meshes to gpu"); } - void MeshManager::delete_gfx_resource(Mesh* mesh) { + void MeshManager::init_mesh(Mesh* mesh) { + assert(mesh); + + auto& entry = m_meshes[mesh]; + entry.weak_ref = WeakRef(mesh); + + array_view> vb = mesh->get_vertex_buffers(); + std::vector> gfx_vb(vb.size()); + for (std::size_t i = 0; i < vb.size(); i++) { + gfx_vb[i] = m_gfx_driver->make_vert_buffer(static_cast(vb[i]->size()), mesh->get_mem_usage(), SIDDBG(mesh->get_name().str() + " vert_buffer i=" + std::to_string(i))); + } + mesh->set_gfx_vertex_buffers(std::move(gfx_vb)); + + array_view> ib = mesh->get_index_buffers(); + std::vector> gfx_ib(ib.size()); + for (std::size_t i = 0; i < ib.size(); i++) { + gfx_ib[i] = m_gfx_driver->make_index_buffer(static_cast(ib[i]->size()), mesh->get_mem_usage(), SIDDBG(mesh->get_name().str() + " index_buffer i=" + std::to_string(i))); + } + mesh->set_gfx_index_buffers(std::move(gfx_ib)); + + mesh->set_mesh_callback(m_callback); } - void MeshManager::upload_gfx_data(Mesh* mesh, GfxCmdListRef& cmd_list) { + void MeshManager::delete_mesh(Mesh* mesh) { + assert(mesh); + + mesh->release_gfx_buffers(); + } + + void MeshManager::upload_mesh(Mesh* mesh, const GfxCmdListRef& cmd) { + WG_PROFILE_CPU_MESH("MeshManager::upload_mesh"); + WG_PROFILE_GPU_SCOPE(cmd, "TextureManager::upload_texture"); + + array_view> vb = mesh->get_vertex_buffers(); + array_view> gfx_vb = mesh->get_gfx_vertex_buffers(); + { + WG_PROFILE_GPU_SCOPE(cmd.get(), "upload_vert_buffers"); + + for (std::size_t i = 0; i < vb.size(); i++) { + cmd->update_vert_buffer(gfx_vb[i], 0, static_cast(vb[i]->size()), {vb[i]->buffer(), vb[i]->size()}); + } + } + + array_view> ib = mesh->get_index_buffers(); + array_view> gfx_ib = mesh->get_gfx_index_buffers(); + { + WG_PROFILE_GPU_SCOPE(cmd.get(), "upload_index_buffers"); + + for (std::size_t i = 0; i < ib.size(); i++) { + cmd->update_index_buffer(gfx_ib[i], 0, static_cast(ib[i]->size()), {ib[i]->buffer(), ib[i]->size()}); + } + } } }// namespace wmoge \ No newline at end of file diff --git a/engine/runtime/mesh/mesh_manager.hpp b/engine/runtime/mesh/mesh_manager.hpp index cddee8307..b9306643b 100644 --- a/engine/runtime/mesh/mesh_manager.hpp +++ b/engine/runtime/mesh/mesh_manager.hpp @@ -38,12 +38,6 @@ namespace wmoge { - /** @brief Managed mesh state */ - enum class MeshState { - PendingUpload, - Inited - }; - /** * @class MeshManager * @brief Manager for gpu meshes for rendering @@ -54,22 +48,26 @@ namespace wmoge { public: MeshManager(class IocContainer* ioc); - Ref create_mesh(MeshFlags flags); + Ref create_mesh(MeshDesc& desc); void add_mesh(const Ref& mesh); void remove_mesh(Mesh* mesh); - void init_mesh(Mesh* mesh); + void queue_mesh_upload(Mesh* mesh); bool has_mesh(Mesh* mesh); - void upload_meshes(); + void flush_meshes_upload(); private: - void create_gfx_resource(Mesh* mesh); - void delete_gfx_resource(Mesh* mesh); - void upload_gfx_data(Mesh* mesh, GfxCmdListRef& cmd_list); + void init_mesh(Mesh* mesh); + void delete_mesh(Mesh* mesh); + void upload_mesh(Mesh* mesh, const GfxCmdListRef& cmd); private: + enum class State { + PendingUpload = 0 + }; + struct Entry { - WeakRef weak_ref; - Mask state; + WeakRef weak_ref; + Mask state; }; flat_map m_meshes; diff --git a/engine/runtime/system/engine.cpp b/engine/runtime/system/engine.cpp index f6278ffbc..745819093 100644 --- a/engine/runtime/system/engine.cpp +++ b/engine/runtime/system/engine.cpp @@ -163,6 +163,7 @@ namespace wmoge { m_gfx_driver->begin_frame(m_frame_id, windows); m_texture_manager->flust_textures_upload(); + m_mesh_manager->flush_meshes_upload(); m_scene_manager->update(); diff --git a/template/main.cpp b/template/main.cpp index adcbc4283..02a663c31 100644 --- a/template/main.cpp +++ b/template/main.cpp @@ -218,7 +218,7 @@ class TemplateApplication : public GameApplication { Ref scene; Ref tex2d; Ref texCube; - WeakRef mesh; + Ref mesh; Ref shader; };