diff options
| -rw-r--r-- | src/components.hpp | 10 | ||||
| -rw-r--r-- | src/entities.cpp | 281 | ||||
| -rw-r--r-- | src/entities.hpp | 1 | ||||
| -rw-r--r-- | src/window.cpp | 10 |
4 files changed, 268 insertions, 34 deletions
diff --git a/src/components.hpp b/src/components.hpp index cd79e4b..0de9592 100644 --- a/src/components.hpp +++ b/src/components.hpp @@ -22,6 +22,12 @@ struct Entity { bool isMarkedForRemoval = false; }; +struct BufferBindingDetails { + VkBuffer buffer = VK_NULL_HANDLE; + uint32_t firstBinding = 0; + uint32_t bindingCount = 0; + VkDeviceSize offsets[1] = {0}; +}; struct CompGrBinds { EntityHandle entHandle = EntityHandle_MAX; GrBindsHandle grBindsHandle = GrBindsHandle_MAX; @@ -44,6 +50,10 @@ struct CompGrBinds { uint32_t indexBindingCount = 0; VkDeviceSize indexOffsets = 0; VkDeviceSize indexCount = 0; + BufferBindingDetails physVertBD; + BufferBindingDetails physNormBD; + BufferBindingDetails physUvBD; + BufferBindingDetails physIndxBD; VkBuffer instanceBuffer = VK_NULL_HANDLE; uint32_t instanceFirstBinding = 0; uint32_t instanceBindingCount = 0; diff --git a/src/entities.cpp b/src/entities.cpp index bdd6709..23632c7 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -1,9 +1,12 @@ #include "entities.hpp" +#include "math-helpers.hpp" #include "physics.hpp" +#include "window.hpp" #include <BulletCollision/CollisionShapes/btConvexHullShape.h> +#include <BulletCollision/CollisionShapes/btConvexPolyhedron.h> #include <vulkan/vulkan_core.h> DynArray<EntityType> GlobalEntityTypes{16}; @@ -33,6 +36,39 @@ int64_t EntityType_FindByEntityHandle(EntityHandle handle) { return -1; } +void CalculateCombinedMemReqs(uint64_t memReqsCount, VkMemoryRequirements *memReqs, VkMemoryRequirements &combinedMemReqs) { + combinedMemReqs.alignment = memReqs[0].alignment; + combinedMemReqs.memoryTypeBits = memReqs[0].memoryTypeBits; + for (long i = 1; i < memReqsCount; ++i) { + combinedMemReqs.memoryTypeBits = memReqs[i].memoryTypeBits; + if (combinedMemReqs.alignment == memReqs[i].alignment) { + continue; + } + VkDeviceSize larger, smaller; + if (combinedMemReqs.alignment > memReqs[i].alignment) { + larger = combinedMemReqs.alignment; + smaller = memReqs[i].alignment; + } else { + larger = memReqs[i].alignment; + smaller = combinedMemReqs.alignment; + } + if (larger % smaller == 0) { + combinedMemReqs.alignment = larger; + continue; + } + int combined = larger * smaller; + while ((combined / 2) % 2 == 0 && (combined / 2) % larger == 0) { + combined /= 2; + } + combinedMemReqs.alignment = combined; + } + for (long i = 0; i < memReqsCount; ++i) { + uint32_t alignmentPadding = memReqs[i].size % combinedMemReqs.alignment; + memReqs[i].size += (alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding); + combinedMemReqs.size += memReqs[i].size; + } +} + void EntityType_Load(EntityType &et) { assert(et.startingInstanceCount > 0); if (et.modelFile != nullptr && et.modelFile != CAFE_BABE(char)) { @@ -435,33 +471,7 @@ void EntityType_Load(EntityType &et) { combinedMemReqs.alignment = vkMemoryRequirements[0].alignment; combinedMemReqs.memoryTypeBits = 0; combinedMemReqs.size = 0; - for (long i = 1; i < expectedBufferCount; ++i) { - if (combinedMemReqs.alignment == vkMemoryRequirements[i].alignment) { - continue; - } - int larger, smaller; - if (combinedMemReqs.alignment > vkMemoryRequirements[i].alignment) { - larger = combinedMemReqs.alignment; - smaller = vkMemoryRequirements[i].alignment; - } else { - larger = vkMemoryRequirements[i].alignment; - smaller = combinedMemReqs.alignment; - } - if (larger % smaller == 0) { - combinedMemReqs.alignment = larger; - continue; - } - int combined = larger * smaller; - while ((combined / 2) % 2 == 0 && (combined / 2) % larger == 0) { - combined /= 2; - } - combinedMemReqs.alignment = combined; - } - for (long i = 0; i < expectedBufferCount; ++i) { - uint32_t alignmentPadding = vkMemoryRequirements[i].size % combinedMemReqs.alignment; - combinedMemReqs.size += vkMemoryRequirements[i].size + (alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding); - combinedMemReqs.memoryTypeBits |= vkMemoryRequirements[i].memoryTypeBits; - } + CalculateCombinedMemReqs(expectedBufferCount, vkMemoryRequirements, combinedMemReqs); // create VkDeviceMemory VkMemoryAllocateInfo vkMemoryAllocateInfo; @@ -614,11 +624,214 @@ void EntityType_Load(EntityType &et) { vkBindBufferMemory(vkDevice, grBinds.instanceBuffer, et.deviceMemoryInst, 0); // bullet + btConvexHullShape *shape; { - et.bt.shape = Pke_New<btConvexHullShape>(MemBkt_Bullet); + shape = Pke_New<btConvexHullShape>(MemBkt_Bullet); btScalar *vertDataPointer = reinterpret_cast<btScalar *>(accVert.buffer_view->buffer->data); vertDataPointer += accVert.buffer_view->offset; - new (et.bt.shape) btConvexHullShape(vertDataPointer, accVert.count, accVert.stride); + new (shape) btConvexHullShape(vertDataPointer, accVert.count, accVert.stride); + shape->initializePolyhedralFeatures(); + shape->optimizeConvexHull(); + et.bt.shape = shape; + } + assert(shape != nullptr); + + // set up convex hull debug + { + const btConvexPolyhedron *pol = shape->getConvexPolyhedron(); + DynArray<glm::vec3> vertexes{pol->m_vertices.size(), MemBkt_Bullet}; + DynArray<glm::vec3> normals{pol->m_vertices.size(), MemBkt_Bullet}; + DynArray<glm::vec2> uv{pol->m_vertices.size(), MemBkt_Bullet}; + DynArray<uint16_t> indexes{pol->m_faces.size() * 6, MemBkt_Bullet}; + for (long i = 0; i < pol->m_vertices.size(); ++i) { + btVector3 norm = pol->m_vertices[i]; + auto &glmVert = vertexes.Push(); + BulletToGlm(norm, glmVert); + norm.safeNormalize(); + auto &glmNorm = normals.Push(); + BulletToGlm(norm, glmNorm); + uv.Push({norm.x(), norm.y()}); + } + for (long i = 0; i < pol->m_faces.size(); ++i) { + for (long k = 2; k < pol->m_faces[i].m_indices.size(); ++k) { + indexes.Push(pol->m_faces[i].m_indices[0]); + indexes.Push(pol->m_faces[i].m_indices[k - 1]); + indexes.Push(pol->m_faces[i].m_indices[k]); + } + } + + VkBufferCreateInfo physBufferCI; + physBufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + physBufferCI.pNext = nullptr; + physBufferCI.flags = {}; + physBufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + physBufferCI.queueFamilyIndexCount = 1; + physBufferCI.pQueueFamilyIndices = &graphicsFamilyIndex; + + VkMemoryRequirements memReqs[4]; + + // vertex + index = 0; + physBufferCI.size = sizeof(glm::vec3) * vertexes.Count(); + physBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physVertBD.buffer); + vkGetBufferMemoryRequirements(vkDevice, grBinds.physVertBD.buffer, &memReqs[index]); + if (memReqs[index].size != physBufferCI.size) { + vkDestroyBuffer(vkDevice, grBinds.physVertBD.buffer, vkAllocator); + physBufferCI.size = memReqs[index].size; + vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physVertBD.buffer); + } + grBinds.physVertBD.bindingCount = vertexes.Count(); + grBinds.physVertBD.firstBinding = index; + + // norm + index = 1; + physBufferCI.size = sizeof(glm::vec3) * normals.Count(); + physBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physNormBD.buffer); + vkGetBufferMemoryRequirements(vkDevice, grBinds.physNormBD.buffer, &memReqs[index]); + if (memReqs[index].size != physBufferCI.size) { + vkDestroyBuffer(vkDevice, grBinds.physNormBD.buffer, vkAllocator); + physBufferCI.size = memReqs[index].size; + vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physNormBD.buffer); + } + grBinds.physNormBD.bindingCount = normals.Count(); + grBinds.physNormBD.firstBinding = index; + + // uv + index = 2; + physBufferCI.size = sizeof(glm::vec2) * uv.Count(); + physBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physUvBD.buffer); + vkGetBufferMemoryRequirements(vkDevice, grBinds.physUvBD.buffer, &memReqs[index]); + if (memReqs[index].size != physBufferCI.size) { + vkDestroyBuffer(vkDevice, grBinds.physUvBD.buffer, vkAllocator); + physBufferCI.size = memReqs[index].size; + vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physUvBD.buffer); + } + grBinds.physUvBD.bindingCount = uv.Count(); + grBinds.physUvBD.firstBinding = index; + + // index + index = 3; + physBufferCI.size = sizeof(glm::vec2) * uv.Count(); + physBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physIndxBD.buffer); + vkGetBufferMemoryRequirements(vkDevice, grBinds.physIndxBD.buffer, &memReqs[index]); + if (memReqs[index].size != physBufferCI.size) { + vkDestroyBuffer(vkDevice, grBinds.physIndxBD.buffer, vkAllocator); + physBufferCI.size = memReqs[index].size; + vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physIndxBD.buffer); + } + grBinds.physIndxBD.bindingCount = indexes.Count(); + // grBinds.physIndxBD.firstBinding = index; + + CalculateCombinedMemReqs(4, memReqs, combinedMemReqs); + + // allocate memory + VkMemoryAllocateInfo physVertMemAI; + physVertMemAI.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + physVertMemAI.pNext = nullptr; + physVertMemAI.allocationSize = combinedMemReqs.size; + physVertMemAI.memoryTypeIndex = combinedMemReqs.memoryTypeBits; + physVertMemAI.memoryTypeIndex = FindMemoryTypeIndex(combinedMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + vkAllocateMemory(vkDevice, &physVertMemAI, vkAllocator, &et.deviceMemoryPhysVert); + + runningOffset = 0; + vkBindBufferMemory(vkDevice, grBinds.physVertBD.buffer, et.deviceMemoryPhysVert, runningOffset); + runningOffset += memReqs[0].size; + vkBindBufferMemory(vkDevice, grBinds.physNormBD.buffer, et.deviceMemoryPhysVert, runningOffset); + runningOffset += memReqs[1].size; + vkBindBufferMemory(vkDevice, grBinds.physUvBD.buffer, et.deviceMemoryPhysVert, runningOffset); + runningOffset += memReqs[2].size; + vkBindBufferMemory(vkDevice, grBinds.physIndxBD.buffer, et.deviceMemoryPhysVert, runningOffset); + + // create transfer items && transfer + { + VkDeviceMemory transferDeviceMemory; + VkBuffer transferBuffer; + void *data; + BeginTransferBuffer(combinedMemReqs.size, transferBuffer, transferDeviceMemory, data); + memset(data, '\0', combinedMemReqs.size); + runningOffset = 0; + + char *dstPtr = nullptr; + char *srcPtr = nullptr; + + dstPtr = static_cast<char *>(data) + runningOffset; + srcPtr = reinterpret_cast<char *>(vertexes.GetPtr()); + memcpy(dstPtr, srcPtr, sizeof(glm::vec3) * vertexes.Count()); + runningOffset += memReqs[0].size; + + dstPtr = static_cast<char *>(data) + runningOffset; + srcPtr = reinterpret_cast<char *>(normals.GetPtr()); + memcpy(dstPtr, srcPtr, sizeof(glm::vec3) * normals.Count()); + runningOffset += memReqs[1].size; + + dstPtr = static_cast<char *>(data) + runningOffset; + srcPtr = reinterpret_cast<char *>(uv.GetPtr()); + memcpy(dstPtr, srcPtr, sizeof(glm::vec2) * uv.Count()); + runningOffset += memReqs[2].size; + + dstPtr = static_cast<char *>(data) + runningOffset; + srcPtr = reinterpret_cast<char *>(indexes.GetPtr()); + memcpy(dstPtr, srcPtr, sizeof(uint16_t) * indexes.Count()); + + VkCommandBufferBeginInfo vkCommandBufferBeginInfo; + vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + vkCommandBufferBeginInfo.pNext = nullptr; + // TODO consider single-use? + vkCommandBufferBeginInfo.flags = 0; + vkCommandBufferBeginInfo.pInheritanceInfo = nullptr; + vkBeginCommandBuffer(transferCommandBuffer, &vkCommandBufferBeginInfo); + VkBufferCopy bufferCopys[expectedBufferCount]; + for (long i = 0; i < expectedBufferCount; ++i) { + bufferCopys[i].dstOffset = 0; + } + index = 0; + runningOffset = 0; + bufferCopys[index].srcOffset = runningOffset; + bufferCopys[index].size = memReqs[index].size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.physVertBD.buffer, 1, &bufferCopys[index]); + runningOffset += memReqs[index].size; + index+=1; + + bufferCopys[index].srcOffset = runningOffset; + bufferCopys[index].size = memReqs[index].size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.physNormBD.buffer, 1, &bufferCopys[index]); + runningOffset += memReqs[index].size; + index+=1; + + bufferCopys[index].srcOffset = runningOffset; + bufferCopys[index].size = memReqs[index].size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.physUvBD.buffer, 1, &bufferCopys[index]); + runningOffset += memReqs[index].size; + index+=1; + + bufferCopys[index].srcOffset = runningOffset; + bufferCopys[index].size = memReqs[index].size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.physIndxBD.buffer, 1, &bufferCopys[index]); + // runningOffset += memReqs[index].size; + // index+=1; + + vkEndCommandBuffer(transferCommandBuffer); + + VkSubmitInfo submitInfo; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.pNext = nullptr; + submitInfo.waitSemaphoreCount = 0; + submitInfo.pWaitSemaphores = nullptr; + submitInfo.pWaitDstStageMask = nullptr; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &transferCommandBuffer; + submitInfo.signalSemaphoreCount = 0; + submitInfo.pSignalSemaphores = nullptr; + vkQueueSubmit(transferQueue, 1, &submitInfo, nullptr); + vkQueueWaitIdle(transferQueue); + + EndTransferBuffer(transferBuffer, transferDeviceMemory); + } } // cleanup @@ -756,6 +969,14 @@ void EntityType_Teardown() { 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); @@ -767,6 +988,8 @@ void EntityType_Teardown() { 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->modelsDir) diff --git a/src/entities.hpp b/src/entities.hpp index e16097c..522fe68 100644 --- a/src/entities.hpp +++ b/src/entities.hpp @@ -20,6 +20,7 @@ struct EntityType { GrBindsHandle grBindsHandle = GrBindsHandle_MAX; VkDeviceMemory deviceMemoryVert = VK_NULL_HANDLE; VkDeviceMemory deviceMemoryInst = VK_NULL_HANDLE; + VkDeviceMemory deviceMemoryPhysVert = VK_NULL_HANDLE; VkDeviceMemory deviceMemoryTexture = VK_NULL_HANDLE; VkImage textureImage = VK_NULL_HANDLE; VkImageView textureImageView = VK_NULL_HANDLE; diff --git a/src/window.cpp b/src/window.cpp index 4c6b598..bb83b32 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -2294,13 +2294,13 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { if (pkeSettings.isRenderingDebug) { vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.TextureWireframe); vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.vkPipelineLayout_Texture, 0, 1, &pkeDebugHitbox.vkDescriptorSets[imageIndex], 0, {}); - vkCmdBindIndexBuffer(commandBuffer, pkeDebugHitbox.indexBuffer, 0, VK_INDEX_TYPE_UINT16); - vkCmdBindVertexBuffers(commandBuffer, 0, 1, &pkeDebugHitbox.vertexBuffer, offsets); - vkCmdBindVertexBuffers(commandBuffer, 1, 1, &pkeDebugHitbox.normalsBuffer, offsets); - vkCmdBindVertexBuffers(commandBuffer, 2, 1, &pkeDebugHitbox.uvBuffer, offsets); + vkCmdBindVertexBuffers(commandBuffer, binder->physVertBD.firstBinding, 1, &binder->physVertBD.buffer, binder->physVertBD.offsets); + vkCmdBindVertexBuffers(commandBuffer, binder->physNormBD.firstBinding, 1, &binder->physNormBD.buffer, binder->physVertBD.offsets); + vkCmdBindVertexBuffers(commandBuffer, binder->physUvBD.firstBinding, 1, &binder->physUvBD.buffer, binder->physVertBD.offsets); + vkCmdBindIndexBuffer(commandBuffer, binder->physIndxBD.buffer, binder->physIndxBD.offsets[0], VK_INDEX_TYPE_UINT16); - vkCmdDrawIndexed(commandBuffer, 36, binder->instanceCounter, 0, 0, 0); + vkCmdDrawIndexed(commandBuffer, binder->physIndxBD.bindingCount, binder->instanceCounter, 0, 0, 0); } } } |
