diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2024-01-04 17:27:54 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2024-01-04 17:27:54 -0500 |
| commit | b0e0814374d934a62e434b65d02d23d3884bce80 (patch) | |
| tree | 894d98ed1fdb77ffebb16d20fa885272001fe0cb /src | |
| parent | 25648cbd7273c66ab6fc9d5e647ee0268da1f4d8 (diff) | |
refactor to allow unloading a single EntityType
Diffstat (limited to 'src')
| -rw-r--r-- | src/ecs.cpp | 9 | ||||
| -rw-r--r-- | src/entities.cpp | 206 | ||||
| -rw-r--r-- | src/entities.hpp | 1 | ||||
| -rw-r--r-- | src/game.cpp | 1 |
4 files changed, 165 insertions, 52 deletions
diff --git a/src/ecs.cpp b/src/ecs.cpp index c33caaa..34eb701 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -127,7 +127,9 @@ void ECS_Tick_Early(double delta) { instBucketIndex = clonedEnt.instanceHandle.bucketIndex; instBucket = &Comp_Instance_BucketContainer.buckets[instBucketIndex]; inst = &instBucket->instances[clonedEnt.instanceHandle.itemIndex]; - grBinds = &Comp_GrBinds_BucketContainer.buckets[inst->grBindsHandle.bucketIndex].compGrBinds[inst->grBindsHandle.itemIndex]; + if (inst->grBindsHandle != GrBindsHandle_MAX) { + grBinds = &Comp_GrBinds_BucketContainer.buckets[inst->grBindsHandle.bucketIndex].compGrBinds[inst->grBindsHandle.itemIndex]; + } } if (grBinds == nullptr && clonedEnt.grBindsHandle != GrBindsHandle_MAX) { grBinds = &Comp_GrBinds_BucketContainer.buckets[clonedEnt.grBindsHandle.bucketIndex].compGrBinds[clonedEnt.grBindsHandle.itemIndex]; @@ -168,6 +170,11 @@ void ECS_Tick_Early(double delta) { inst->bt.rigidBody = CAFE_BABE(btRigidBody); inst->bt.motionState = CAFE_BABE(btDefaultMotionState); } else if (grBinds != nullptr) { + grBinds->entHandle = EntityHandle_MAX; + grBinds->grBindsHandle = GrBindsHandle_MAX; + grBinds->vkPipelineLayout = VK_NULL_HANDLE; + grBinds->graphicsPipeline = VK_NULL_HANDLE; + grBinds->collisionCallback = PkeCallback{}; /* * 2023-09-05 JB note - the Vulkan assets (device memory, buffers, * pipeline layout, and descriptor set) are unloaded elsewhere, just, diff --git a/src/entities.cpp b/src/entities.cpp index f837f60..496874a 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -15,6 +15,12 @@ #include <vulkan/vulkan_core.h> DynArray<EntityType> GlobalEntityTypes{16}; +struct EntToTeardown { + EntityHandle handle = EntityHandle_MAX; + CompGrBinds *grBinds[1] = {nullptr}; + uint8_t ticksToWait = 0; +}; +DynArray<EntToTeardown> EntityTypesToTeardown{16}; void EntityType_Init() { long entityTypeCount = GlobalEntityTypes.Count(); @@ -1029,6 +1035,136 @@ void EntityType_Load(EntityType &et) { Pke_EndTransientBucket(helper.bkt); } +void EntityType_Unload(EntityType &et, CompGrBinds *grBindsArr[1]) { + if (et.modelAssetKey[0] == '\0') return; + et.modelAssetKey[0] = '\0'; + + for (long k = 0; k < et.detailsCount; ++k) { + EntityTypeDetails &etd = et.details[k]; + auto *grBinds = grBindsArr[k]; + if (grBinds != nullptr) { + if (grBinds->vkDescriptorSets != nullptr && etd.vkDescriptorPool != VK_NULL_HANDLE) { + // 2023-09-27 - JCB + // We are not setting the pool flag for allowing freeing descriptor sets + // so all we need to do is destroy the pool + // If we switch to a global pool, we will need to free here, and + // destroy the pool outside of this loop + vkDestroyDescriptorPool(vkDevice, etd.vkDescriptorPool, vkAllocator); + grBinds->vkDescriptorSets = CAFE_BABE(VkDescriptorSet); + } + if (grBinds->vertexBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); + grBinds->vertexBuffer = VK_NULL_HANDLE; + grBinds->vertexFirstBinding = 0; + grBinds->vertexBindingCount = 0; + grBinds->vertexOffsets = 0; + + if (grBinds->normalsBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->normalsBuffer, vkAllocator); + grBinds->normalsBuffer = VK_NULL_HANDLE; + grBinds->normalsFirstBinding = 0; + grBinds->normalsBindingCount = 0; + grBinds->normalsOffsets = 0; + + if (grBinds->uvBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->uvBuffer, vkAllocator); + grBinds->uvBuffer = VK_NULL_HANDLE; + grBinds->uvFirstBinding = 0; + grBinds->uvBindingCount = 0; + grBinds->uvOffsets = 0; + + if (grBinds->indexBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->indexBuffer, vkAllocator); + grBinds->indexBuffer = VK_NULL_HANDLE; + grBinds->indexBindingCount = 0; + grBinds->indexOffsets = 0; + grBinds->indexCount = 0; + + if (grBinds->physVertBD.buffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->physVertBD.buffer, vkAllocator); + grBinds->physVertBD.buffer = VK_NULL_HANDLE; + grBinds->physVertBD.firstBinding = 0; + grBinds->physVertBD.bindingCount = 0; + grBinds->physVertBD.offsets[0] = 0; + + if (grBinds->physNormBD.buffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->physNormBD.buffer, vkAllocator); + grBinds->physNormBD.buffer = VK_NULL_HANDLE; + grBinds->physNormBD.firstBinding = 0; + grBinds->physNormBD.bindingCount = 0; + grBinds->physNormBD.offsets[0] = 0; + + if (grBinds->physUvBD.buffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->physUvBD.buffer, vkAllocator); + grBinds->physUvBD.buffer = VK_NULL_HANDLE; + grBinds->physUvBD.firstBinding = 0; + grBinds->physUvBD.bindingCount = 0; + grBinds->physUvBD.offsets[0] = 0; + + if (grBinds->physIndxBD.buffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->physIndxBD.buffer, vkAllocator); + grBinds->physIndxBD.buffer = VK_NULL_HANDLE; + grBinds->physIndxBD.firstBinding = 0; + grBinds->physIndxBD.bindingCount = 0; + grBinds->physIndxBD.offsets[0] = 0; + + if (grBinds->instanceBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->instanceBuffer, vkAllocator); + grBinds->instanceBuffer = VK_NULL_HANDLE; + grBinds->instanceFirstBinding = 0; + grBinds->instanceBindingCount = 0; + grBinds->instanceCounter = 0; + grBinds->instanceBufferMaxCount = 0; + grBinds->instanceOffsets = 0; + } + + if (etd.textureImageView != VK_NULL_HANDLE) + vkDestroyImageView(vkDevice, etd.textureImageView, vkAllocator); + etd.textureImageView = VK_NULL_HANDLE; + + if (etd.textureImage != VK_NULL_HANDLE) + vkDestroyImage(vkDevice, etd.textureImage, vkAllocator); + etd.textureImage = VK_NULL_HANDLE; + + } + if (et.deviceMemoryInst != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, et.deviceMemoryInst, vkAllocator); + et.deviceMemoryInst = VK_NULL_HANDLE; + + if (et.deviceMemoryVert != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, et.deviceMemoryVert, vkAllocator); + et.deviceMemoryVert = VK_NULL_HANDLE; + + if (et.deviceMemoryPhysVert != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, et.deviceMemoryPhysVert, vkAllocator); + et.deviceMemoryPhysVert = VK_NULL_HANDLE; + + if (et.deviceMemoryTexture != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, et.deviceMemoryTexture, vkAllocator); + et.deviceMemoryTexture = VK_NULL_HANDLE; + + if (et.entityTypeCode) + Pke_Delete<char>(et.entityTypeCode, strlen(et.entityTypeCode)); + et.entityTypeCode = CAFE_BABE(char); +} + +void EntityType_Tick(double delta) { + const auto count = EntitiesToBeRemoved.Count(); + int64_t detailIndex = -1; + for (long i = 0; i < count; ++i) { + if (auto index = EntityType_FindByEntityHandle(EntitiesToBeRemoved[i], detailIndex); index > -1) { + if (auto *grBinds = ECS_GetGrBinds(EntitiesToBeRemoved[i]); grBinds != nullptr) { + auto &td = EntityTypesToTeardown.Push(); + td.handle = EntitiesToBeRemoved[i]; + td.ticksToWait = 1; + for (long k = 0; k < GlobalEntityTypes[index].detailsCount; ++k) { + td.grBinds[k] = grBinds; + } + } + } + } +} + void EntityType_Tick_Late(double delta) { while (EntitiesWithExcessInstances.Count() != 0) { auto entHandle = EntitiesWithExcessInstances.Pop(); @@ -1039,6 +1175,17 @@ void EntityType_Tick_Late(double delta) { auto &grBinds = *ECS_GetGrBinds(etd.entityHandle); EntityType_RolloverInstances(et, grBinds); } + for (int64_t i = EntityTypesToTeardown.Count() - 1; i >= 0; --i) { + auto &td = EntityTypesToTeardown[i]; + td.ticksToWait -= 1; + if (td.ticksToWait == 0) { + int64_t detailIndex = -1; + auto index = EntityType_FindByEntityHandle(td.handle, detailIndex); + EntityType_Unload(GlobalEntityTypes[index], td.grBinds); + GlobalEntityTypes.Remove(index); + EntityTypesToTeardown.Remove(i); + } + } } void EntityType_RolloverInstances(EntityType &et, CompGrBinds &grBinds) { @@ -1138,60 +1285,17 @@ void EntityType_RolloverInstances(EntityType &et, CompGrBinds &grBinds) { } void EntityType_Teardown() { - long entityTypeCount = GlobalEntityTypes.Count(); - for (long i = 0; i < entityTypeCount; ++i) { + for (int64_t i = GlobalEntityTypes.Count() - 1; i >= 0; --i) { if (GlobalEntityTypes[i].modelAssetKey[0] == '\0') continue; - EntityType *et = &GlobalEntityTypes[i]; - - for (long k = 0; k < et->detailsCount; ++k) { - EntityTypeDetails &etd = et->details[k]; - auto *grBinds = ECS_GetGrBinds(etd.entityHandle); - if (grBinds != nullptr) { - if (grBinds->vkDescriptorSets != nullptr && etd.vkDescriptorPool != VK_NULL_HANDLE) { - // 2023-09-27 - JCB - // We are not setting the pool flag for allowing freeing descriptor sets - // so all we need to do is destroy the pool - // If we switch to a global pool, we will need to free here, and - // destroy the pool outside of this loop - vkDestroyDescriptorPool(vkDevice, etd.vkDescriptorPool, vkAllocator); - Pke_Delete<VkDescriptorSet>(grBinds->vkDescriptorSets, MAX_FRAMES_IN_FLIGHT); - } - if (grBinds->vertexBuffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); - if (grBinds->normalsBuffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, grBinds->normalsBuffer, vkAllocator); - if (grBinds->uvBuffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, grBinds->uvBuffer, vkAllocator); - if (grBinds->indexBuffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, grBinds->indexBuffer, vkAllocator); - if (grBinds->physVertBD.buffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, grBinds->physVertBD.buffer, vkAllocator); - if (grBinds->physNormBD.buffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, grBinds->physNormBD.buffer, vkAllocator); - if (grBinds->physUvBD.buffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, grBinds->physUvBD.buffer, vkAllocator); - if (grBinds->physIndxBD.buffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, grBinds->physIndxBD.buffer, vkAllocator); - if (grBinds->instanceBuffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, grBinds->instanceBuffer, vkAllocator); - } - - if (etd.textureImageView != VK_NULL_HANDLE) - vkDestroyImageView(vkDevice, etd.textureImageView, vkAllocator); - if (etd.textureImage != VK_NULL_HANDLE) - vkDestroyImage(vkDevice, etd.textureImage, vkAllocator); + EntityType &et = GlobalEntityTypes[i]; + CompGrBinds *grBindsArr[1] = {nullptr}; + for (long k = 0; k < et.detailsCount; ++k) { + const EntityTypeDetails &etd = et.details[k]; + grBindsArr[k] = ECS_GetGrBinds(etd.entityHandle); } - if (et->deviceMemoryInst != VK_NULL_HANDLE) - vkFreeMemory(vkDevice, et->deviceMemoryInst, vkAllocator); - if (et->deviceMemoryVert != VK_NULL_HANDLE) - vkFreeMemory(vkDevice, et->deviceMemoryVert, vkAllocator); - if (et->deviceMemoryPhysVert != VK_NULL_HANDLE) - vkFreeMemory(vkDevice, et->deviceMemoryPhysVert, vkAllocator); - if (et->deviceMemoryTexture != VK_NULL_HANDLE) - vkFreeMemory(vkDevice, et->deviceMemoryTexture, vkAllocator); - if (et->entityTypeCode) - Pke_Delete<char>(et->entityTypeCode, strlen(et->entityTypeCode)); + EntityType_Unload(et, grBindsArr); } GlobalEntityTypes.~DynArray(); + EntityTypesToTeardown.~DynArray(); } diff --git a/src/entities.hpp b/src/entities.hpp index f822336..cbb8e15 100644 --- a/src/entities.hpp +++ b/src/entities.hpp @@ -44,6 +44,7 @@ void EntityType_Init(); int64_t EntityType_FindByTypeCode(const char *typeCode); int64_t EntityType_FindByEntityHandle(EntityHandle handle, int64_t &detailIndex); void EntityType_Load(EntityType &et); +void EntityType_Tick(double delta); void EntityType_Tick_Late(double delta); void EntityType_RolloverInstances(EntityType &et, CompGrBinds &grBinds); void EntityType_Teardown(); diff --git a/src/game.cpp b/src/game.cpp index b6d3321..9849e5d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -514,6 +514,7 @@ void Game_Tick(double delta) { ECS_Tick_Early(delta); ECS_Tick(delta); + EntityType_Tick(delta); PkeInput_Tick(delta); const auto pluginCount = LoadedPkePlugins.Count(); |
