mesh pool

This commit is contained in:
2026-09-15 02:23:41 -07:00
parent 05fe3c2ee8
commit c97db37b31
2 changed files with 38 additions and 16 deletions
+31 -14
View File
@@ -4,6 +4,10 @@
namespace sophia { namespace sophia {
namespace {
constexpr u32 GENERATION_MASK = (1u << 12) - 1;
} // namespace
MeshPool::MeshPool(Device& device) : device{device} {} MeshPool::MeshPool(Device& device) : device{device} {}
MeshPool::~MeshPool() = default; MeshPool::~MeshPool() = default;
@@ -12,30 +16,43 @@ MeshHandle MeshPool::create(const Mesh::Builder& builder) {
auto mesh = std::make_unique<Mesh>(device, builder); auto mesh = std::make_unique<Mesh>(device, builder);
if (!freeList.empty()) { if (!freeList.empty()) {
MeshHandle handle = freeList.back(); u32 index = freeList.back();
freeList.pop_back(); freeList.pop_back();
meshes[handle] = std::move(mesh); slots[index].mesh = std::move(mesh);
return handle; return MeshHandle{index, slots[index].generation};
} }
meshes.push_back(std::move(mesh)); slots.push_back(Slot{std::move(mesh), 0});
return static_cast<MeshHandle>(meshes.size() - 1); return MeshHandle{static_cast<u32>(slots.size() - 1), 0};
} }
const Mesh& MeshPool::get(MeshHandle handle) const { const Mesh& MeshPool::get(MeshHandle handle) const {
SOPHIA_ASSERT(handle < meshes.size(), "invalid MeshHandle:", handle); SOPHIA_ASSERT(handle.isValid(), "invalid MeshHandle");
SOPHIA_ASSERT(meshes[handle] != nullptr, SOPHIA_ASSERT(handle.index < slots.size(),
"MeshHandle refers to a released mesh:", handle); "MeshHandle index out of range:", handle.index);
return *meshes[handle];
const Slot& slot = slots[handle.index];
SOPHIA_ASSERT(slot.generation == handle.generation,
"stale MeshHandle (generation mismatch):", handle.index);
SOPHIA_ASSERT(slot.mesh != nullptr,
"MeshHandle refers to a released mesh:", handle.index);
return *slot.mesh;
} }
void MeshPool::release(MeshHandle handle) { void MeshPool::release(MeshHandle handle) {
SOPHIA_ASSERT(handle < meshes.size(), "invalid MeshHandle:", handle); SOPHIA_ASSERT(handle.isValid(), "invalid MeshHandle");
SOPHIA_ASSERT(meshes[handle] != nullptr, SOPHIA_ASSERT(handle.index < slots.size(),
"MeshHandle already released:", handle); "MeshHandle index out of range:", handle.index);
meshes[handle].reset(); Slot& slot = slots[handle.index];
freeList.push_back(handle); SOPHIA_ASSERT(slot.generation == handle.generation,
"stale MeshHandle (generation mismatch):", handle.index);
SOPHIA_ASSERT(slot.mesh != nullptr,
"MeshHandle already released:", handle.index);
slot.mesh.reset();
slot.generation = (slot.generation + 1) & GENERATION_MASK;
freeList.push_back(handle.index);
} }
} // namespace sophia } // namespace sophia
+7 -2
View File
@@ -21,10 +21,15 @@ class MeshPool {
void release(MeshHandle handle); void release(MeshHandle handle);
private: private:
struct Slot {
std::unique_ptr<Mesh> mesh;
u32 generation = 0;
};
Device& device; Device& device;
std::vector<std::unique_ptr<Mesh>> meshes; std::vector<Slot> slots;
std::vector<MeshHandle> freeList; std::vector<u32> freeList;
}; };
} // namespace sophia } // namespace sophia