diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-09-12 14:31:09 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-09-12 14:31:09 -0400 |
| commit | b4ba9eb4f1fe02d65945a263beb3185a617a414b (patch) | |
| tree | bc53bafd81c989b555792171eb9c505f08984aff /src/entities.cpp | |
| parent | e6d5d4ff0dd3d3640860c23034955ff6db149827 (diff) | |
load gltf files - no shaders yet
Diffstat (limited to 'src/entities.cpp')
| -rw-r--r-- | src/entities.cpp | 238 |
1 files changed, 223 insertions, 15 deletions
diff --git a/src/entities.cpp b/src/entities.cpp index 2887074..75b56f4 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -1,19 +1,40 @@ #include "entities.hpp" -#include "ecs.hpp" -#include <vulkan/vulkan_core.h> -void EntityType_Init() {} +DynArray<EntityType> globalEntityTypes{16}; + +void EntityType_Init() { + globalEntityTypes.Push( + EntityType { + .modelFile = "assets/models/cube.gltf", + .entityTypeCode = "EntTypeCube", + .entityHandle = ECS_CreateEntity(), + .startingInstanceCount = 16, + .Importer_GLTF = { + .AccessorIndexVertex = 0, + .AccessorIndexNormal = 1, + .AccessorIndexUV = 2, + .AccessorIndexIndex = 3, + } + } + ); + + long entityTypeCount = globalEntityTypes.Count(); + for (long i = 0; i < entityTypeCount; ++i) { + EntityType_Load(globalEntityTypes[i]); + } +} void EntityType_Load(EntityType &et) { + assert(et.startingInstanceCount > 0); if (et.modelFile != nullptr && et.modelFile != CAFE_BABE(char)) { - assert(et.vkPipelineLayoutCreateInfo != nullptr && et.vkPipelineLayoutCreateInfo != CAFE_BABE(VkPipelineLayoutCreateInfo) && "EntityType with a defined model must also contain appropriate Vulkan CreateInfos"); + // assert(et.vkPipelineLayoutCreateInfo != nullptr && et.vkPipelineLayoutCreateInfo != CAFE_BABE(VkPipelineLayoutCreateInfo) && "EntityType with a defined model must also contain appropriate Vulkan CreateInfos"); AssetHandle assetHandle{AM_Register(et.modelFile)}; const Asset *asset = AM_Get(assetHandle); CompGrBinds &grBinds = ECS_CreateGrBinds(et.entityHandle); - auto vkResult = vkCreatePipelineLayout(vkDevice, et.vkPipelineLayoutCreateInfo, vkAllocator, &grBinds.vkPipelineLayout); - assert(vkResult == VK_SUCCESS); + // auto vkResult = vkCreatePipelineLayout(vkDevice, et.vkPipelineLayoutCreateInfo, vkAllocator, &grBinds.vkPipelineLayout); + // assert(vkResult == VK_SUCCESS); // TODO grBinds.vkDescriptorSet cgltf_options options{}; @@ -21,22 +42,198 @@ void EntityType_Load(EntityType &et) { cgltf_data *gltfData = nullptr; cgltf_result result = cgltf_parse(&options, asset->ptr, asset->size, &gltfData); assert(result == cgltf_result_success); + // TODO consider using AssetHandler OR loading this directly to the GPU + result = cgltf_load_buffers(&options, gltfData, et.modelFile); + assert(result == cgltf_result_success); result = cgltf_validate(gltfData); assert(result == cgltf_result_success); - // create buffers - // TODO + // make sure cgltf can interpret our model + for (long i = 0; i < gltfData->accessors_count; ++i) { + assert(gltfData->accessors[i].type != cgltf_type_invalid); + } + for (long i = 0; i < gltfData->buffers_count; ++i) { + assert(gltfData->buffer_views[i].type != cgltf_buffer_view_type_invalid); + } + assert(et.Importer_GLTF.AccessorIndexVertex > -1); + + VkBufferCreateInfo bufferCI; + bufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferCI.pNext = nullptr; + bufferCI.flags = {}; + bufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + bufferCI.queueFamilyIndexCount = 1; + bufferCI.pQueueFamilyIndices = &graphicsFamilyIndex; + + VkMemoryRequirements vkMemoryRequirements; + + if (et.Importer_GLTF.AccessorIndexVertex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexVertex]; + grBinds.vertexCount = acc.count; + bufferCI.size = acc.buffer_view->size; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.vertexBuffer); + + vkGetBufferMemoryRequirements(vkDevice, grBinds.vertexBuffer, &vkMemoryRequirements); + } + if (et.Importer_GLTF.AccessorIndexNormal > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexNormal]; + grBinds.normalsCount = acc.count; + bufferCI.size = acc.buffer_view->size; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.normalsBuffer); + + VkMemoryRequirements vkMemoryRequirementsNormals; + vkGetBufferMemoryRequirements(vkDevice, grBinds.normalsBuffer, &vkMemoryRequirementsNormals); + vkMemoryRequirements.memoryTypeBits |= vkMemoryRequirementsNormals.memoryTypeBits; + vkMemoryRequirements.size += vkMemoryRequirementsNormals.size; + assert(vkMemoryRequirementsNormals.alignment == vkMemoryRequirements.alignment); + } + if (et.Importer_GLTF.AccessorIndexUV > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexUV]; + grBinds.uvCount = acc.count; + bufferCI.size = acc.buffer_view->size; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.uvBuffer); + + VkMemoryRequirements vkMemoryRequirementsUV; + vkGetBufferMemoryRequirements(vkDevice, grBinds.uvBuffer, &vkMemoryRequirementsUV); + vkMemoryRequirements.memoryTypeBits |= vkMemoryRequirementsUV.memoryTypeBits; + vkMemoryRequirements.size += vkMemoryRequirementsUV.size; + assert(vkMemoryRequirementsUV.alignment == vkMemoryRequirements.alignment); + } + if (et.Importer_GLTF.AccessorIndexIndex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexIndex]; + grBinds.indexCount = acc.count; + bufferCI.size = acc.buffer_view->size; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.indexBuffer); + + VkMemoryRequirements vkMemoryRequirementsIndex; + vkGetBufferMemoryRequirements(vkDevice, grBinds.indexBuffer, &vkMemoryRequirementsIndex); + vkMemoryRequirements.memoryTypeBits |= vkMemoryRequirementsIndex.memoryTypeBits; + vkMemoryRequirements.size += vkMemoryRequirementsIndex.size; + assert(vkMemoryRequirementsIndex.alignment == vkMemoryRequirements.alignment); + } // create VkDeviceMemory VkMemoryAllocateInfo vkMemoryAllocateInfo; vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; vkMemoryAllocateInfo.pNext = nullptr; - vkMemoryAllocateInfo.allocationSize = gltfData->buffers[0].size;; - vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(0, 0); // TODO + vkMemoryAllocateInfo.allocationSize = vkMemoryRequirements.size; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &grBinds.deviceMemoryVert); + + // bind buffers + if (et.Importer_GLTF.AccessorIndexVertex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexVertex]; + assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); + vkBindBufferMemory(vkDevice, grBinds.vertexBuffer, grBinds.deviceMemoryVert, acc.buffer_view->offset); + } + if (et.Importer_GLTF.AccessorIndexNormal > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexNormal]; + assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); + vkBindBufferMemory(vkDevice, grBinds.normalsBuffer, grBinds.deviceMemoryVert, acc.buffer_view->offset); + } + if (et.Importer_GLTF.AccessorIndexUV > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexUV]; + assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); + vkBindBufferMemory(vkDevice, grBinds.uvBuffer , grBinds.deviceMemoryVert, acc.buffer_view->offset); + } + if (et.Importer_GLTF.AccessorIndexIndex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexIndex]; + assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); + vkBindBufferMemory(vkDevice, grBinds.indexBuffer, grBinds.deviceMemoryVert, acc.buffer_view->offset); + } + + // create transfer items && transfer + { + // reminder that we don't need to do instance here, because we're just + // setting up the type. No instances have been created yet. + VkDeviceMemory transferDeviceMemory; + VkBuffer transferBuffer; + VkMemoryRequirements vkMemoryRequirementsTransfer; + + bufferCI.size = vkMemoryRequirements.size; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &transferBuffer); + vkGetBufferMemoryRequirements(vkDevice, transferBuffer, &vkMemoryRequirementsTransfer); + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemoryRequirementsTransfer.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + // note, this should be identical (other than memory type) to the dst buffer + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &transferDeviceMemory); + vkBindBufferMemory(vkDevice, transferBuffer, transferDeviceMemory, 0); + void *data; + vkMapMemory(vkDevice, transferDeviceMemory, 0, gltfData->buffers[0].size, 0, &data); + memcpy(data, gltfData->buffers[0].data, gltfData->buffers[0].size); + vkUnmapMemory(vkDevice, transferDeviceMemory); + + 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[4]; + for (long i = 0; i < 4; ++i) { + bufferCopys[i].dstOffset = 0; + } + long index = 0; + if (et.Importer_GLTF.AccessorIndexVertex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexVertex]; + bufferCopys[index].srcOffset = acc.buffer_view->offset; + bufferCopys[index].size = acc.buffer_view->size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.vertexBuffer, 1, &bufferCopys[index]); + index += 1; + } + if (et.Importer_GLTF.AccessorIndexNormal > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexNormal]; + bufferCopys[index].srcOffset = acc.buffer_view->offset; + bufferCopys[index].size = acc.buffer_view->size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.normalsBuffer, 1, &bufferCopys[index]); + index += 1; + } + if (et.Importer_GLTF.AccessorIndexUV > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexUV]; + bufferCopys[index].srcOffset = acc.buffer_view->offset; + bufferCopys[index].size = acc.buffer_view->size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.uvBuffer, 1, &bufferCopys[index]); + index += 1; + } + if (et.Importer_GLTF.AccessorIndexIndex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexIndex]; + bufferCopys[index].srcOffset = acc.buffer_view->offset; + bufferCopys[index].size = acc.buffer_view->size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.indexBuffer, 1, &bufferCopys[index]); + } + + 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); - vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &grBinds.deviceMemory); + vkDestroyBuffer(vkDevice, transferBuffer, vkAllocator); + vkFreeMemory(vkDevice, transferDeviceMemory, vkAllocator); + } - // TODO bind buffers to memory + // set up instance buffer + bufferCI.size = sizeof(InstPos) * et.startingInstanceCount; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.instanceBuffer); + VkMemoryRequirements vkMemoryRequirementsInst; + vkGetBufferMemoryRequirements(vkDevice, grBinds.instanceBuffer, &vkMemoryRequirementsInst); + vkMemoryAllocateInfo.allocationSize = vkMemoryRequirementsInst.size; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemoryRequirementsInst.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &grBinds.deviceMemoryInst); + vkBindBufferMemory(vkDevice, grBinds.instanceBuffer, grBinds.deviceMemoryInst, 0); // cleanup cgltf_free(gltfData); @@ -49,8 +246,19 @@ void EntityType_Teardown() { if (globalEntityTypes[i].modelFile == nullptr) continue; auto *grBinds = ECS_GetGrBinds(globalEntityTypes[i].entityHandle); vkDestroyPipelineLayout(vkDevice, grBinds->vkPipelineLayout, vkAllocator); - vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); - vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); - vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); + 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->instanceBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->instanceBuffer, vkAllocator); + if (grBinds->deviceMemoryInst != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, grBinds->deviceMemoryInst, vkAllocator); + if (grBinds->deviceMemoryVert != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, grBinds->deviceMemoryVert, vkAllocator); } } |
