diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-10-02 19:51:10 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-10-02 19:51:10 -0400 |
| commit | 4899815c69894bba3eb1a6faa8ccbbc676751728 (patch) | |
| tree | e3d5895b35d060d193ec59ccdeaf65dfbad6e145 /src/ecs.cpp | |
| parent | 2bdee2ce549b1306cafb1d657624eeed4cf7225a (diff) | |
instancing now works as intended
Diffstat (limited to 'src/ecs.cpp')
| -rw-r--r-- | src/ecs.cpp | 215 |
1 files changed, 143 insertions, 72 deletions
diff --git a/src/ecs.cpp b/src/ecs.cpp index b0f9250..9458506 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -1,7 +1,8 @@ #include "ecs.hpp" -#include <new> +#include "vendor/glm_include.hpp" +#include "window.hpp" TypeSafeInt_B(EntityHandle); const uint64_t maxBucketItemCount = 256; @@ -115,7 +116,6 @@ void ECS_Tick_Early(double delta) { instBucketIndex = b; } if (inst != nullptr) { - grBinds->instances.Remove(inst->index); for (long bi = instBucketIndex; bi <= Comp_Instance_BucketContainer.bucketCounter; ++bi) { uint64_t instCounter = 0; if (bi == Comp_Instance_BucketContainer.bucketCounter) { @@ -132,74 +132,139 @@ void ECS_Tick_Early(double delta) { continue; } bucket.instances[ii].index -= 1; + bucket.instances[ii].isNeedingUpdated = true; } } + grBinds->instanceCounter -=1; inst->entHandle = EntityHandle_MAX; inst->grBindsHandle = GrBindsHandle_MAX; inst->index = ECS_UNSET_VAL; inst->instanceHandle = InstanceHandle_MAX; - inst->ptr = CAFE_BABE(InstPos); + inst->isNeedingUpdated = false; } else if (grBinds != nullptr) { /* * 2023-09-05 JB note - the Vulkan assets (device memory, buffers, * pipeline layout, and descriptor set) are unloaded elsewhere, just, * as they were created elsewhere. */ - DynArrayDestroy(&grBinds->instances); } } entitiesMarkedForRemoval.Resize(0); } +struct InstanceBufferCopyChunk { + uint64_t startingIndex; + uint64_t endingIndex; + DynArray<glm::mat4> mats{0}; + VkBufferCopy dstBufferCopy; +}; +struct InstanceBufferCopy { + CompGrBinds *grBinds = nullptr; + VkDeviceSize runningSize = 0; + DynArray<InstanceBufferCopyChunk> chunks{4}; +}; void ECS_Tick_Late(double delta) { - for (long b = 0; b <= Comp_GrBinds_BucketContainer.bucketCounter; ++b) { - auto &bkt = Comp_GrBinds_BucketContainer.buckets[b]; - long count = Comp_GrBinds_BucketContainer.bucketCounter == b ? Comp_GrBinds_BucketContainer.itemCounter >> 32 : maxBucketItemCount; - for (long i = 0; i < count; ++i) { - auto &grBinds = bkt.compGrBinds[i]; - if (grBinds.isInstanceBufferNeedingUpdated) { - VkDeviceSize byteCount = sizeof(InstPos) * grBinds.instances.Count(); - VkBuffer transferBuffer; - VkDeviceMemory transferMemory; - void *deviceData; - BeginTransferBuffer(byteCount, transferBuffer, transferMemory, deviceData); - memcpy(deviceData, grBinds.instances.GetPtr(), byteCount); - { - VkCommandBufferBeginInfo cbbi; - cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - cbbi.pNext = nullptr; - cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - cbbi.pInheritanceInfo = nullptr; - - vkBeginCommandBuffer(transferCommandBuffer, &cbbi); - - VkBufferCopy vkBufferCopy; - vkBufferCopy.srcOffset = 0; - vkBufferCopy.dstOffset = 0; - vkBufferCopy.size = byteCount; - - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.instanceBuffer, 1, &vkBufferCopy); - - vkEndCommandBuffer(transferCommandBuffer); - - VkSubmitInfo vkSubmitInfo{}; - vkSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - vkSubmitInfo.pNext = nullptr; - vkSubmitInfo.waitSemaphoreCount = 0; - vkSubmitInfo.pWaitSemaphores = nullptr; - vkSubmitInfo.pWaitDstStageMask = nullptr; - vkSubmitInfo.commandBufferCount = 1; - vkSubmitInfo.pCommandBuffers = &transferCommandBuffer; - vkSubmitInfo.signalSemaphoreCount = 0; - vkSubmitInfo.pSignalSemaphores = nullptr; - vkQueueSubmit(transferQueue, 1, &vkSubmitInfo, nullptr); - vkQueueWaitIdle(transferQueue); - vkResetCommandBuffer(transferCommandBuffer, 0); + DynArray<InstanceBufferCopy> bufferUpdates{0}; + for (long b = 0; b <= Comp_Instance_BucketContainer.bucketCounter; ++b) { + auto &bkt = Comp_Instance_BucketContainer.buckets[b]; + long count = Comp_Instance_BucketContainer.bucketCounter == b ? Comp_Instance_BucketContainer.itemCounter >> 32 : maxBucketItemCount; + for (uint32_t i = 0; i < count; ++i) { + auto &inst = bkt.instances[i]; + if (inst.isNeedingUpdated == false) + continue; + + GrBindsHandle_T grBindsHandle_t{static_cast<GrBindsHandle_T>(inst.grBindsHandle)}; + auto b_inner = Buckets_GetBucketIndex(grBindsHandle_t); + auto bi_inner = Buckets_GetItemIndex(grBindsHandle_t); + auto &grBinds = Comp_GrBinds_BucketContainer.buckets[b_inner].compGrBinds[bi_inner]; + + InstanceBufferCopy *bfrUpdate = nullptr; + for (long u = 0; u < bufferUpdates.Count(); ++u) { + if (bufferUpdates[u].grBinds->grBindsHandle == inst.grBindsHandle) { + bfrUpdate = &bufferUpdates[u]; + } + } + if (bfrUpdate == nullptr) { + bufferUpdates.Push({ + .grBinds = &grBinds, + }); + bfrUpdate = &bufferUpdates[bufferUpdates.Count() - 1]; + } + + InstanceBufferCopyChunk *chunk = nullptr; + for (long ii = 0; ii < bfrUpdate->chunks.Count(); ++ii) { + if (bfrUpdate->chunks[ii].endingIndex == inst.index - 1) { + chunk = &bfrUpdate->chunks[ii]; + chunk->endingIndex += 1; + break; } - EndTransferBuffer(transferBuffer, transferMemory); - grBinds.isInstanceBufferNeedingUpdated = false; } + if (chunk == nullptr) { + bfrUpdate->chunks.Push({ + .startingIndex = inst.index, + .endingIndex = inst.index, + }); + chunk = &bfrUpdate->chunks[bfrUpdate->chunks.Count() - 1]; + chunk->dstBufferCopy.dstOffset = sizeof(glm::mat4) * inst.index; + } + + chunk->mats.Push( + glm::translate(glm::mat4(1), inst.instPos.pos) + * glm::mat4_cast(inst.instPos.rot) + * glm::scale(glm::mat4(1), inst.instPos.scale)); + bfrUpdate->runningSize += sizeof(glm::mat4); + inst.isNeedingUpdated = false; + } + } + while (bufferUpdates.Count() > 0) { + InstanceBufferCopy ibc = bufferUpdates.Pop(); + + VkDeviceSize instanceBytes = sizeof(glm::mat4); + VkDeviceSize byteCount = ibc.runningSize; + VkBuffer transferBuffer; + VkDeviceMemory transferMemory; + void *deviceData; + BeginTransferBuffer(byteCount, transferBuffer, transferMemory, deviceData); + VkDeviceSize runningOffset = 0; + for (long i = 0; i < ibc.chunks.Count(); ++i) { + auto *chunk = &ibc.chunks[i]; + memcpy(static_cast<char *>(deviceData) + runningOffset, chunk->mats.GetPtr(), byteCount); + chunk->dstBufferCopy.srcOffset = runningOffset; + chunk->dstBufferCopy.size = instanceBytes * (chunk->endingIndex - chunk->startingIndex + 1); + runningOffset += chunk->dstBufferCopy.size; + } + assert(runningOffset == ibc.runningSize); + + { + VkCommandBufferBeginInfo cbbi; + cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cbbi.pNext = nullptr; + cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + cbbi.pInheritanceInfo = nullptr; + + vkBeginCommandBuffer(transferCommandBuffer, &cbbi); + + for (long i = 0; i < ibc.chunks.Count(); ++i) { + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, ibc.grBinds->instanceBuffer, 1, &ibc.chunks[i].dstBufferCopy); + } + + vkEndCommandBuffer(transferCommandBuffer); + + VkSubmitInfo vkSubmitInfo{}; + vkSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + vkSubmitInfo.pNext = nullptr; + vkSubmitInfo.waitSemaphoreCount = 0; + vkSubmitInfo.pWaitSemaphores = nullptr; + vkSubmitInfo.pWaitDstStageMask = nullptr; + vkSubmitInfo.commandBufferCount = 1; + vkSubmitInfo.pCommandBuffers = &transferCommandBuffer; + vkSubmitInfo.signalSemaphoreCount = 0; + vkSubmitInfo.pSignalSemaphores = nullptr; + vkQueueSubmit(transferQueue, 1, &vkSubmitInfo, nullptr); + vkQueueWaitIdle(transferQueue); + vkResetCommandBuffer(transferCommandBuffer, 0); } + EndTransferBuffer(transferBuffer, transferMemory); } } @@ -261,25 +326,24 @@ CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityType ent->instanceHandle = InstanceHandle{newHandle}; GrBindsHandle_T grBindsHandle_t{static_cast<GrBindsHandle_T>(entTypeEnt->grBindsHandle)}; - auto b2 = Buckets_GetBucketIndex(grBindsHandle_t); - auto i2 = Buckets_GetItemIndex(grBindsHandle_t); - auto *grBinds = &Comp_GrBinds_BucketContainer.buckets[b2].compGrBinds[i2]; - grBinds->isInstanceBufferNeedingUpdated = true; - grBinds->instanceBindingCount = 1; auto b = Buckets_GetBucketIndex(newHandle); auto i = Buckets_GetItemIndex(newHandle); - auto *comp = &Comp_Instance_BucketContainer.buckets[b].instances[i]; + auto *instBkt = &Comp_Instance_BucketContainer.buckets[b]; + auto *comp = &instBkt->instances[i]; comp = new (comp) CompInstance{}; comp->entHandle = entHandle; + + auto b2 = Buckets_GetBucketIndex(grBindsHandle_t); + auto i2 = Buckets_GetItemIndex(grBindsHandle_t); + auto *grBinds = &Comp_GrBinds_BucketContainer.buckets[b2].compGrBinds[i2]; + comp->grBindsHandle = grBinds->grBindsHandle; comp->instanceHandle = ent->instanceHandle; - comp->index = grBinds->instances.Count(); - grBinds->instances.Push({ - .pos = glm::vec3(0), - .rot = glm::vec3(1), - .scale = glm::vec3(1), - }); - comp->ptr = &grBinds->instances[comp->index]; + comp->index = grBinds->instanceCounter++; + comp->instPos.pos = glm::vec3(0, 0, 0); + comp->instPos.rot = glm::quat(1, 0, 0, 0); + comp->instPos.scale = glm::vec3(1, 1, 1); + comp->isNeedingUpdated = true; return *comp; } @@ -295,16 +359,23 @@ CompInstance *ECS_GetInstance(EntityHandle entHandle) { auto i = Buckets_GetItemIndex(instanceHandle_t); auto *inst = &Comp_Instance_BucketContainer.buckets[b].instances[i]; - if (inst->index == ECS_UNSET_VAL) - return nullptr; - if (inst->grBindsHandle == GrBindsHandle_MAX) - return nullptr; + return inst; +} - GrBindsHandle_T grBindsHandle_t{static_cast<GrBindsHandle_T>(inst->grBindsHandle)}; - auto b2 = Buckets_GetBucketIndex(grBindsHandle_t); - auto i2 = Buckets_GetItemIndex(grBindsHandle_t); - auto grBinds = &Comp_GrBinds_BucketContainer.buckets[b2].compGrBinds[i2]; +void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos) { + Entity *ent = nullptr; + ECS_GetEntity_Inner(entHandle, ent); - inst->ptr = &grBinds->instances[inst->index]; - return inst; + if (ent->instanceHandle == InstanceHandle_MAX) + return; + + InstanceHandle_T instanceHandle_t{static_cast<InstanceHandle_T>(ent->instanceHandle)}; + auto b = Buckets_GetBucketIndex(instanceHandle_t); + auto i = Buckets_GetItemIndex(instanceHandle_t); + auto *inst = &Comp_Instance_BucketContainer.buckets[b].instances[i]; + + inst->instPos.pos = instPos.pos; + inst->instPos.rot = instPos.rot; + inst->instPos.scale = instPos.scale; + inst->isNeedingUpdated = true; } |
