diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2024-01-03 16:35:09 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2024-01-03 16:35:09 -0500 |
| commit | 1ffa486edd70406627f3e329351184dafebc1aea (patch) | |
| tree | 494a3289a185260b089b3396944d7268090bceba /src/entities.cpp | |
| parent | be543940e3c561ee2ab8eb315211112b97065476 (diff) | |
checkpoint - EntityTypeDetails array
Diffstat (limited to 'src/entities.cpp')
| -rw-r--r-- | src/entities.cpp | 915 |
1 files changed, 541 insertions, 374 deletions
diff --git a/src/entities.cpp b/src/entities.cpp index ad72b04..df6130b 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -1,7 +1,9 @@ #include "entities.hpp" +#include "ecs.hpp" #include "math-helpers.hpp" +#include "memory.hpp" #include "physics.hpp" #include "static/missing-texture.hpp" #include "window.hpp" @@ -9,6 +11,7 @@ #include <BulletCollision/CollisionShapes/btConvexHullShape.h> #include <BulletCollision/CollisionShapes/btConvexPolyhedron.h> #include <filesystem> +#include <type_traits> #include <vulkan/vulkan_core.h> DynArray<EntityType> GlobalEntityTypes{16}; @@ -29,16 +32,24 @@ int64_t EntityType_FindByTypeCode(const char *typeCode) { return -1; } -int64_t EntityType_FindByEntityHandle(EntityHandle handle) { +int64_t EntityType_FindByEntityHandle(EntityHandle handle, int64_t &detailIndex) { for (int64_t i = 0; i < GlobalEntityTypes.Count(); ++i) { if (GlobalEntityTypes[i].entityHandle == handle) { + detailIndex = -1; return i; } + for (int64_t k = 0; k < GlobalEntityTypes[i].detailsCount; ++k) { + if (GlobalEntityTypes[i].details[k].entityHandle == handle) { + detailIndex = k; + return i; + } + } } return -1; } void CalculateCombinedMemReqs(uint64_t memReqsCount, VkMemoryRequirements *memReqs, VkMemoryRequirements &combinedMemReqs) { + combinedMemReqs.size = 0; combinedMemReqs.alignment = memReqs[0].alignment; combinedMemReqs.memoryTypeBits = memReqs[0].memoryTypeBits; for (long i = 1; i < memReqsCount; ++i) { @@ -71,12 +82,262 @@ void CalculateCombinedMemReqs(uint64_t memReqsCount, VkMemoryRequirements *memRe } } -void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle textureAssetHandle) { +struct EntityTypeDetails_LoadHelperStruct { + EntityTypeDetails *etd = nullptr; + AssetHandle textureAssetHandle = AssetHandle_MAX; + const Asset *textureAsset = nullptr; + CompGrBinds *grBinds = nullptr; + struct { + DynArray<glm::vec3> *vertexes = nullptr; + DynArray<glm::vec3> *normals = nullptr; + DynArray<glm::vec2> *uv = nullptr; + DynArray<uint16_t> *indexes = nullptr; + } physDbg; +}; +struct EntityType_LoadHelperStruct { + MemBucket *bkt = nullptr; + EntityType &et; + DynArray<EntityTypeDetails_LoadHelperStruct> *etdHelpers = nullptr; + const cgltf_data *gltfData = nullptr; + const Asset *modelBinAsset = nullptr; + DynArray<VkMemoryRequirements> *vertMemoryRequirements = nullptr; + DynArray<VkMemoryRequirements> *instMemoryRequirements = nullptr; + DynArray<VkMemoryRequirements> *physVertMemoryRequirements = nullptr; + DynArray<VkMemoryRequirements> *textureMemoryRequirements = nullptr; + VkMemoryRequirements vertMemoryRequirementsCombined{}; + VkMemoryRequirements instMemoryRequirementsCombined{}; + VkMemoryRequirements physVertMemoryRequirementsCombined{}; + VkMemoryRequirements textureMemoryRequirementsCombined{}; +}; + +void EntityType_PreLoad(EntityType_LoadHelperStruct &helper) { + + const long expectedBufferCount = 4; + helper.vertMemoryRequirements->Reserve(helper.et.detailsCount * expectedBufferCount); + helper.instMemoryRequirements->Reserve(helper.et.detailsCount); + helper.physVertMemoryRequirements->Reserve(helper.et.detailsCount * expectedBufferCount); + helper.textureMemoryRequirements->Reserve(helper.et.detailsCount); + + VkBuffer buffer; + 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; + + VkImage image; + VkImageCreateInfo vkImageCreateInfo; + vkImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + vkImageCreateInfo.pNext = nullptr; + vkImageCreateInfo.flags = 0; + vkImageCreateInfo.imageType = VK_IMAGE_TYPE_2D; + vkImageCreateInfo.mipLevels = 1; + vkImageCreateInfo.arrayLayers = 1; + vkImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + vkImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + vkImageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + vkImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + vkImageCreateInfo.queueFamilyIndexCount = 0; + vkImageCreateInfo.pQueueFamilyIndices = nullptr; + vkImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + for (int64_t i = 0; i < helper.et.detailsCount; ++i) { + EntityTypeDetails &etd = helper.et.details[i]; + EntityTypeDetails_LoadHelperStruct &etdHelper = helper.etdHelpers->Push(); + etdHelper.etd = &etd; + etd.entityHandle = ECS_CreateEntity(helper.et.entityHandle); + auto &grBinds = ECS_CreateGrBinds(etd.entityHandle); + etdHelper.grBinds = &grBinds; + etd.grBindsHandle = grBinds.grBindsHandle; + etdHelper.physDbg.vertexes = reinterpret_cast<DynArray<glm::vec3> *>(Pke_New(sizeof(DynArray<glm::vec3>), 64, helper.bkt)); + etdHelper.physDbg.normals = reinterpret_cast<DynArray<glm::vec3> *>(Pke_New(sizeof(DynArray<glm::vec3>), 64, helper.bkt)); + etdHelper.physDbg.uv = reinterpret_cast<DynArray<glm::vec2> *>(Pke_New(sizeof(DynArray<glm::vec2>), 64, helper.bkt)); + etdHelper.physDbg.indexes = reinterpret_cast<DynArray<uint16_t> *>(Pke_New(sizeof(DynArray<uint16_t>), 64, helper.bkt)); + new (etdHelper.physDbg.vertexes) DynArray<glm::vec3>(helper.bkt); + new (etdHelper.physDbg.normals) DynArray<glm::vec3>(helper.bkt); + new (etdHelper.physDbg.uv) DynArray<glm::vec2>(helper.bkt); + new (etdHelper.physDbg.indexes) DynArray<uint16_t>(helper.bkt); + + /* + * phys + */ + btConvexHullShape *shape; + { + shape = Pke_New<btConvexHullShape>(MemBkt_Bullet); + btScalar *vertDataPointer = reinterpret_cast<btScalar *>(helper.modelBinAsset->ptr); + /* TODO JCB - 2024-01-02 + * we shouldn't assume that the first index is the vertexes + */ + uint64_t vertIndex = (i * expectedBufferCount); + vertDataPointer += helper.gltfData->accessors[vertIndex].buffer_view->offset; + new (shape) btConvexHullShape(vertDataPointer, helper.gltfData->accessors[vertIndex].count, helper.gltfData->accessors[vertIndex].stride); + shape->optimizeConvexHull(); + shape->initializePolyhedralFeatures(); + etd.bt.shape = shape; + } + assert(shape != nullptr); + // convex hull debug + const btConvexPolyhedron *pol = shape->getConvexPolyhedron(); + etdHelper.physDbg.vertexes->Reserve(pol->m_vertices.size()); + etdHelper.physDbg.normals->Reserve(pol->m_vertices.size()); + etdHelper.physDbg.uv->Reserve(pol->m_vertices.size()); + etdHelper.physDbg.indexes->Reserve(pol->m_faces.size()); + for (long k = 0; k < pol->m_vertices.size(); ++k) { + btVector3 norm = pol->m_vertices[k]; + auto &glmVert = etdHelper.physDbg.vertexes->Push(); + BulletToGlm(norm, glmVert); + norm.safeNormalize(); + auto &glmNorm = etdHelper.physDbg.normals->Push(); + BulletToGlm(norm, glmNorm); + etdHelper.physDbg.uv->Push({norm.x(), norm.y()}); + } + for (long ii = 0; ii < pol->m_faces.size(); ++ii) { + for (long k = 2; k < pol->m_faces[ii].m_indices.size(); ++k) { + etdHelper.physDbg.indexes->Push(pol->m_faces[ii].m_indices[0]); + etdHelper.physDbg.indexes->Push(pol->m_faces[ii].m_indices[k - 1]); + etdHelper.physDbg.indexes->Push(pol->m_faces[ii].m_indices[k]); + } + } + for (int64_t index = 0; index < expectedBufferCount; ++index) { + /* TODO JCB - 2024-01-02 + * lol + */ + if (index == 0) { + bufferCI.size = sizeof(glm::vec3) * etdHelper.physDbg.vertexes->Count(); + } else if (index == 1) { + bufferCI.size = sizeof(glm::vec3) * etdHelper.physDbg.normals->Count(); + } else if (index == 2) { + bufferCI.size = sizeof(glm::vec2) * etdHelper.physDbg.uv->Count(); + } else if (index == 3) { + bufferCI.size = sizeof(uint16_t) * etdHelper.physDbg.indexes->Count(); + } + if (index == 3) { + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + } else { + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + } + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &buffer); + vkGetBufferMemoryRequirements(vkDevice, buffer, &helper.physVertMemoryRequirements->Push()); + vkDestroyBuffer(vkDevice, buffer, vkAllocator); + } + + /* + * verts + */ + for (int64_t index = 0; index < expectedBufferCount; ++index) { + const auto &acc = helper.gltfData->accessors[(expectedBufferCount * i) + index]; + bufferCI.size = acc.buffer_view->size; + /* TODO JCB - 2024-01-02 + * If our bindings ever change, == 3 isn't good enough to determine + * which of all the buffers is the index buffer + */ + if (index == 3) { + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + } else { + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + } + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &buffer); + vkGetBufferMemoryRequirements(vkDevice, buffer, &helper.vertMemoryRequirements->Push()); + vkDestroyBuffer(vkDevice, buffer, vkAllocator); + } + + /* + * instance + */ + uint32_t instBufferStartingCount = etd.startingInstanceCount; + instBufferStartingCount = instBufferStartingCount < 1 ? 1 : instBufferStartingCount; + bufferCI.size = sizeof(glm::mat4) * instBufferStartingCount; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &buffer); + vkGetBufferMemoryRequirements(vkDevice, buffer, &helper.instMemoryRequirements->Push()); + vkDestroyBuffer(vkDevice, buffer, vkAllocator); + + /* + * texture + */ + int32_t pixelWidth, pixelHeight, pixelChannels; + etdHelper.textureAssetHandle = AssetHandle{AM_GetHandle(etd.textureAssetKey)}; + if (etdHelper.textureAssetHandle != AssetHandle_MAX) { + etdHelper.textureAsset = AM_Get(etdHelper.textureAssetHandle); + stbi_uc *pixels = stbi_load_from_memory(static_cast<stbi_uc *>(etdHelper.textureAsset->ptr), etdHelper.textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha); + assert(pixels != nullptr && "sbti_load failed to load image."); + stbi_image_free(pixels); + } else { + pixelWidth = 2; + pixelHeight = 2; + pixelChannels = 4; + } + + VkFormat imageFormat = VK_FORMAT_R8G8B8A8_SRGB; + if (pixelChannels == 3) { + imageFormat = VK_FORMAT_R8G8B8_SRGB; + } else if (pixelChannels == 2) { + imageFormat = VK_FORMAT_R8G8_SRGB; + } else if (pixelChannels == 1) { + imageFormat = VK_FORMAT_R8_SRGB; + } else { + assert(pixelChannels != 0 && pixelChannels < 5); + } + vkImageCreateInfo.format = imageFormat; + vkImageCreateInfo.extent = VkExtent3D { + .width = static_cast<uint32_t>(pixelWidth), + .height = static_cast<uint32_t>(pixelHeight), + .depth = 1 + }; + vkCreateImage(vkDevice, &vkImageCreateInfo, vkAllocator, &image); + vkGetImageMemoryRequirements(vkDevice, image, &helper.textureMemoryRequirements->Push()); + vkDestroyImage(vkDevice, image, vkAllocator); + } + + VkMemoryAllocateInfo vkMemoryAllocateInfo; + vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + vkMemoryAllocateInfo.pNext = nullptr; + + /* + * phys + */ + CalculateCombinedMemReqs(helper.physVertMemoryRequirements->Count(), helper.physVertMemoryRequirements->GetPtr(), helper.physVertMemoryRequirementsCombined); + vkMemoryAllocateInfo.allocationSize = helper.physVertMemoryRequirementsCombined.size; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(helper.physVertMemoryRequirementsCombined.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &helper.et.deviceMemoryPhysVert); + + /* + * verts + */ + CalculateCombinedMemReqs(helper.vertMemoryRequirements->Count(), helper.vertMemoryRequirements->GetPtr(), helper.vertMemoryRequirementsCombined); + vkMemoryAllocateInfo.allocationSize = helper.vertMemoryRequirementsCombined.size; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(helper.vertMemoryRequirementsCombined.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &helper.et.deviceMemoryVert); + + /* + * instance + */ + CalculateCombinedMemReqs(helper.instMemoryRequirements->Count(), helper.instMemoryRequirements->GetPtr(), helper.instMemoryRequirementsCombined); + vkMemoryAllocateInfo.allocationSize = helper.instMemoryRequirementsCombined.size; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(helper.instMemoryRequirementsCombined.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &helper.et.deviceMemoryInst); + + /* + * texture + */ + CalculateCombinedMemReqs(helper.textureMemoryRequirements->Count(), helper.textureMemoryRequirements->GetPtr(), helper.textureMemoryRequirementsCombined); + vkMemoryAllocateInfo.allocationSize = helper.textureMemoryRequirementsCombined.size; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(helper.textureMemoryRequirementsCombined.memoryTypeBits, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + if (vkMemoryAllocateInfo.memoryTypeIndex == 0) { + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(helper.textureMemoryRequirementsCombined.memoryTypeBits, 0); + } + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &helper.et.deviceMemoryTexture); +} + +void EntityType_LoadTexture(EntityType_LoadHelperStruct &helper, const int64_t index) { + EntityTypeDetails_LoadHelperStruct &etdHelper = (*helper.etdHelpers)[index]; + int32_t pixelWidth, pixelHeight, pixelChannels; stbi_uc *pixels = nullptr; - if (textureAssetHandle != AssetHandle_MAX) { - const Asset *textureAsset = AM_Get(textureAssetHandle); - pixels = stbi_load_from_memory(static_cast<stbi_uc *>(textureAsset->ptr), textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha); + if (etdHelper.textureAssetHandle != AssetHandle_MAX) { + pixels = stbi_load_from_memory(static_cast<stbi_uc *>(etdHelper.textureAsset->ptr), etdHelper.textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha); assert(pixels != nullptr && "sbti_load failed to load image."); } else { pixelWidth = 2; @@ -119,26 +380,15 @@ void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle te vkImageCreateInfo.pQueueFamilyIndices = nullptr; vkImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - vkCreateImage(vkDevice, &vkImageCreateInfo, vkAllocator, &et.textureImage); - - VkMemoryRequirements imageMemReqs; - vkGetImageMemoryRequirements(vkDevice, et.textureImage, &imageMemReqs); - VkMemoryAllocateInfo imageAllocInfo; - imageAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - imageAllocInfo.pNext = nullptr; - imageAllocInfo.allocationSize = imageMemReqs.size; - imageAllocInfo.memoryTypeIndex = FindMemoryTypeIndex(imageMemReqs.memoryTypeBits, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); - if (imageAllocInfo.memoryTypeIndex == 0) { - imageAllocInfo.memoryTypeIndex = FindMemoryTypeIndex(imageMemReqs.memoryTypeBits, 0); - } - vkAllocateMemory(vkDevice, &imageAllocInfo, vkAllocator, &et.deviceMemoryTexture); - vkBindImageMemory(vkDevice, et.textureImage, et.deviceMemoryTexture, 0); + vkCreateImage(vkDevice, &vkImageCreateInfo, vkAllocator, &etdHelper.etd->textureImage); + // TODO calculate padding + vkBindImageMemory(vkDevice, etdHelper.etd->textureImage, helper.et.deviceMemoryTexture, 0); VkImageViewCreateInfo vkImageViewCreateInfo; vkImageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; vkImageViewCreateInfo.pNext = nullptr; vkImageViewCreateInfo.flags = 0; - vkImageViewCreateInfo.image = et.textureImage; + vkImageViewCreateInfo.image = etdHelper.etd->textureImage; // TODO animated textures vkImageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; vkImageViewCreateInfo.format = imageFormat; @@ -158,7 +408,7 @@ void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle te .layerCount = 1, }; - vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &et.textureImageView); + vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &etdHelper.etd->textureImageView); // transition image layout and copy to buffer VkBuffer transferImageBuffer; @@ -176,7 +426,7 @@ void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle te vkImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; vkImageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; vkImageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - vkImageMemoryBarrier.image = et.textureImage; + vkImageMemoryBarrier.image = etdHelper.etd->textureImage; vkImageMemoryBarrier.subresourceRange = VkImageSubresourceRange { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .baseMipLevel = 0, @@ -219,7 +469,7 @@ void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle te .height = static_cast<uint32_t>(pixelHeight), .depth = 1, }; - vkCmdCopyBufferToImage(transferCommandBuffer, transferImageBuffer, et.textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vkBufferImageCopy); + vkCmdCopyBufferToImage(transferCommandBuffer, transferImageBuffer, etdHelper.etd->textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vkBufferImageCopy); vkEndCommandBuffer(transferCommandBuffer); @@ -248,7 +498,7 @@ void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle te vkImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; vkImageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; vkImageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - vkImageMemoryBarrier.image = et.textureImage; + vkImageMemoryBarrier.image = etdHelper.etd->textureImage; vkImageMemoryBarrier.subresourceRange = VkImageSubresourceRange { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .baseMipLevel = 0, @@ -286,9 +536,9 @@ void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle te } // TODO double-check this? - // stbi_image_free(pixels); - if (textureAssetHandle != AssetHandle_MAX) { - AM_Release(textureAssetHandle); + if (etdHelper.textureAssetHandle != AssetHandle_MAX) { + stbi_image_free(pixels); + AM_Release(etdHelper.textureAssetHandle); } // descriptor pool & sets @@ -308,7 +558,7 @@ void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle te vkDescriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes; // consider making me a global pool - auto vkResult = vkCreateDescriptorPool(vkDevice, &vkDescriptorPoolCreateInfo, vkAllocator, &et.vkDescriptorPool); + auto vkResult = vkCreateDescriptorPool(vkDevice, &vkDescriptorPoolCreateInfo, vkAllocator, &etdHelper.etd->vkDescriptorPool); assert(vkResult == VK_SUCCESS); VkDescriptorSetLayout descriptorSets[MAX_FRAMES_IN_FLIGHT]; @@ -318,15 +568,15 @@ void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle te VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo; vkDescriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; vkDescriptorSetAllocateInfo.pNext = nullptr; - vkDescriptorSetAllocateInfo.descriptorPool = et.vkDescriptorPool; + vkDescriptorSetAllocateInfo.descriptorPool = etdHelper.etd->vkDescriptorPool; vkDescriptorSetAllocateInfo.descriptorSetCount = MAX_FRAMES_IN_FLIGHT; vkDescriptorSetAllocateInfo.pSetLayouts = descriptorSets; - grBinds.vkDescriptorSets = Pke_New<VkDescriptorSet>(MAX_FRAMES_IN_FLIGHT); + etdHelper.grBinds->vkDescriptorSets = Pke_New<VkDescriptorSet>(MAX_FRAMES_IN_FLIGHT); for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { - grBinds.vkDescriptorSets[i] = VkDescriptorSet{}; + etdHelper.grBinds->vkDescriptorSets[i] = VkDescriptorSet{}; } - vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, grBinds.vkDescriptorSets); + vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, etdHelper.grBinds->vkDescriptorSets); assert(vkResult == VK_SUCCESS); VkWriteDescriptorSet writeDescriptorSets[2 * MAX_FRAMES_IN_FLIGHT]; @@ -346,7 +596,7 @@ void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle te VkDescriptorImageInfo textureDescriptorInfo; textureDescriptorInfo.sampler = pkePipelines.vkSampler_Texture; - textureDescriptorInfo.imageView = et.textureImageView; + textureDescriptorInfo.imageView = etdHelper.etd->textureImageView; textureDescriptorInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; VkDescriptorBufferInfo vkDescriptorBufferInfo[MAX_FRAMES_IN_FLIGHT]; @@ -360,62 +610,27 @@ void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle te long samplerIndex = uboIndex + 1; writeDescriptorSets[uboIndex].pBufferInfo = &vkDescriptorBufferInfo[i]; - writeDescriptorSets[uboIndex].dstSet = grBinds.vkDescriptorSets[i]; + writeDescriptorSets[uboIndex].dstSet = etdHelper.grBinds->vkDescriptorSets[i]; writeDescriptorSets[samplerIndex].pImageInfo = &textureDescriptorInfo; - writeDescriptorSets[samplerIndex].dstSet = grBinds.vkDescriptorSets[i]; + writeDescriptorSets[samplerIndex].dstSet = etdHelper.grBinds->vkDescriptorSets[i]; } vkUpdateDescriptorSets(vkDevice, 2 * MAX_FRAMES_IN_FLIGHT, writeDescriptorSets, 0, nullptr); } -void EntityType_Load(EntityType &et) { - assert(et.startingInstanceCount > 0); - AssetHandle assetHandle{AM_GetHandle(et.modelAssetKey)}; - assert(assetHandle != AssetHandle_MAX); - - CompGrBinds &grBinds = ECS_CreateGrBinds(et.entityHandle); - /* - * 2023-09-13 - JCB - * I don't like that we're just copying this. - * This should be moved to window.cpp. - */ - grBinds.vkPipelineLayout = pkePipelines.vkPipelineLayout_Texture; - grBinds.graphicsPipeline = pkePipelines.pipelines.Texture; - et.grBindsHandle = grBinds.grBindsHandle; - - // handle texture - AssetHandle textureAssetHandle{AM_GetHandle(et.textureAssetKey)}; - EntityType_LoadTexture(et, grBinds, textureAssetHandle); +void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t meshIndex) { - //handle gltf - const Asset *asset = AM_Get(assetHandle); - cgltf_options options{}; - // TODO allocator - cgltf_data *gltfData = nullptr; - cgltf_result result = cgltf_parse(&options, asset->ptr, asset->size, &gltfData); - assert(result == cgltf_result_success); - // result = cgltf_load_buffers(&options, gltfData, modelPath); - // assert(result == cgltf_result_success); - result = cgltf_validate(gltfData); - assert(result == cgltf_result_success); - assert(gltfData->buffers_count == 1); + EntityTypeDetails_LoadHelperStruct &etdHelper = (*helper.etdHelpers)[meshIndex]; - std::filesystem::path gltfPath{asset->basePath}; - gltfPath.replace_filename(gltfData->buffers[0].uri); - AssetHandle modelBinHandle = AM_Register(gltfPath.c_str(), PKE_ASSET_TYPE_UNSET); + // create and bind buffers - // 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); - assert(et.Importer_GLTF.AccessorIndexNormal > -1); - assert(et.Importer_GLTF.AccessorIndexUV > -1); - assert(et.Importer_GLTF.AccessorIndexIndex > -1); + // TODO load me from gltf data + const long expectedBufferCount = 4; + int64_t accessorIndexVertex = (meshIndex * expectedBufferCount) + 0; + int64_t accessorIndexNormal = (meshIndex * expectedBufferCount) + 1; + int64_t accessorIndexUV = (meshIndex * expectedBufferCount) + 2; + int64_t accessorIndexIndex = (meshIndex * expectedBufferCount) + 3; VkBufferCreateInfo bufferCI; bufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; @@ -425,156 +640,106 @@ void EntityType_Load(EntityType &et) { bufferCI.queueFamilyIndexCount = 1; bufferCI.pQueueFamilyIndices = &graphicsFamilyIndex; - const long expectedBufferCount = 4; - VkMemoryRequirements vkMemoryRequirements[expectedBufferCount]; long index = 0; - - // vertex - assert(et.Importer_GLTF.AccessorIndexVertex > -1); - const auto &accVert = gltfData->accessors[et.Importer_GLTF.AccessorIndexVertex]; - grBinds.vertexFirstBinding = index; - grBinds.vertexBindingCount = 1; - bufferCI.size = accVert.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[index]); - index += 1; - - // normals - assert(et.Importer_GLTF.AccessorIndexNormal > -1); - const auto &accNorm = gltfData->accessors[et.Importer_GLTF.AccessorIndexNormal]; - grBinds.normalsFirstBinding = index; - grBinds.normalsBindingCount = 1; - bufferCI.size = accNorm.buffer_view->size; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.normalsBuffer); - vkGetBufferMemoryRequirements(vkDevice, grBinds.normalsBuffer, &vkMemoryRequirements[index]); - index += 1; - - // uv - assert(et.Importer_GLTF.AccessorIndexUV > -1); - const auto &accUV = gltfData->accessors[et.Importer_GLTF.AccessorIndexUV]; - grBinds.uvFirstBinding = index; - grBinds.uvBindingCount = 1; - bufferCI.size = accUV.buffer_view->size; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.uvBuffer); - vkGetBufferMemoryRequirements(vkDevice, grBinds.uvBuffer, &vkMemoryRequirements[index]); - index += 1; - - // 2023-09-27 - JCB - // I don't know where else to put this - grBinds.instanceFirstBinding = index; - grBinds.instanceBindingCount = 1; - // no index += 1 because index just happens to be the right value here for - // the binding index, whereas binding the IndexBuffer doesn't need a binding index. - - // index - assert(et.Importer_GLTF.AccessorIndexIndex > -1); - const auto &accIndex = gltfData->accessors[et.Importer_GLTF.AccessorIndexIndex]; - grBinds.indexBindingCount = 1; - grBinds.indexCount = accIndex.count; - bufferCI.size = accIndex.buffer_view->size; - bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.indexBuffer); - vkGetBufferMemoryRequirements(vkDevice, grBinds.indexBuffer, &vkMemoryRequirements[index]); - // index += 1; - - vkDestroyBuffer(vkDevice, grBinds.indexBuffer, vkAllocator); - vkDestroyBuffer(vkDevice, grBinds.uvBuffer, vkAllocator); - vkDestroyBuffer(vkDevice, grBinds.normalsBuffer, vkAllocator); - vkDestroyBuffer(vkDevice, grBinds.vertexBuffer, vkAllocator); - - VkMemoryRequirements combinedMemReqs{}; - combinedMemReqs.alignment = vkMemoryRequirements[0].alignment; - combinedMemReqs.memoryTypeBits = 0; - combinedMemReqs.size = 0; - CalculateCombinedMemReqs(expectedBufferCount, vkMemoryRequirements, combinedMemReqs); - - // create VkDeviceMemory - VkMemoryAllocateInfo vkMemoryAllocateInfo; - vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - vkMemoryAllocateInfo.pNext = nullptr; - vkMemoryAllocateInfo.allocationSize = combinedMemReqs.size; - vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(combinedMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &et.deviceMemoryVert); - - // bind buffers uint32_t runningOffset = 0; - uint32_t alignmentPadding; + uint32_t alignmentPadding = 0; // vertex + const auto &accVert = helper.gltfData->accessors[accessorIndexVertex]; uint32_t offsetVert = runningOffset; uint32_t sizeVert = accVert.buffer_view->size; - alignmentPadding = sizeVert % combinedMemReqs.alignment; - alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding; + etdHelper.grBinds->vertexFirstBinding = index; + etdHelper.grBinds->vertexBindingCount = 1; + alignmentPadding = sizeVert % helper.vertMemoryRequirementsCombined.alignment; + alignmentPadding = alignmentPadding == 0 ? 0 : helper.vertMemoryRequirementsCombined.alignment - alignmentPadding; sizeVert += alignmentPadding; bufferCI.size = sizeVert; bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.vertexBuffer); - vkBindBufferMemory(vkDevice, grBinds.vertexBuffer, et.deviceMemoryVert, offsetVert); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->vertexBuffer); + vkBindBufferMemory(vkDevice, etdHelper.grBinds->vertexBuffer, helper.et.deviceMemoryVert, offsetVert); runningOffset += sizeVert; + index += 1; - // norm + // normals + const auto &accNorm = helper.gltfData->accessors[accessorIndexNormal]; uint32_t offsetNorm = runningOffset; uint32_t sizeNorm = accNorm.buffer_view->size; - alignmentPadding = sizeNorm % combinedMemReqs.alignment; - alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding; + etdHelper.grBinds->normalsFirstBinding = index; + etdHelper.grBinds->normalsBindingCount = 1; + alignmentPadding = sizeNorm % helper.vertMemoryRequirementsCombined.alignment; + alignmentPadding = alignmentPadding == 0 ? 0 : helper.vertMemoryRequirementsCombined.alignment - alignmentPadding; sizeNorm += alignmentPadding; bufferCI.size = sizeNorm; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.normalsBuffer); - vkBindBufferMemory(vkDevice, grBinds.normalsBuffer, et.deviceMemoryVert, offsetNorm); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->normalsBuffer); + vkBindBufferMemory(vkDevice, etdHelper.grBinds->normalsBuffer, helper.et.deviceMemoryVert, offsetNorm); runningOffset += sizeNorm; + index += 1; // uv + const auto &accUV = helper.gltfData->accessors[accessorIndexUV]; uint32_t offsetUV = runningOffset; uint32_t sizeUV = accUV.buffer_view->size; - alignmentPadding = sizeUV % combinedMemReqs.alignment; - alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding; + etdHelper.grBinds->uvFirstBinding = index; + etdHelper.grBinds->uvBindingCount = 1; + alignmentPadding = sizeUV % helper.vertMemoryRequirementsCombined.alignment; + alignmentPadding = alignmentPadding == 0 ? 0 : helper.vertMemoryRequirementsCombined.alignment - alignmentPadding; sizeUV += alignmentPadding; bufferCI.size = sizeUV; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.uvBuffer); - vkBindBufferMemory(vkDevice, grBinds.uvBuffer , et.deviceMemoryVert, offsetUV); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->uvBuffer); + vkBindBufferMemory(vkDevice, etdHelper.grBinds->uvBuffer , helper.et.deviceMemoryVert, offsetUV); runningOffset += sizeUV; + index += 1; + + // 2023-09-27 - JCB + // I don't know where else to put this + etdHelper.grBinds->instanceFirstBinding = index; + etdHelper.grBinds->instanceBindingCount = 1; + // no index += 1 because index just happens to be the right value here for + // the binding index, whereas binding the IndexBuffer doesn't need a binding index. // index + const auto &accIndex = helper.gltfData->accessors[accessorIndexIndex]; uint32_t offsetIndex = runningOffset; uint32_t sizeIndex = accIndex.buffer_view->size; - alignmentPadding = sizeIndex % combinedMemReqs.alignment; - alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding; + etdHelper.grBinds->indexBindingCount = 1; + etdHelper.grBinds->indexCount = accIndex.count; + alignmentPadding = sizeIndex % helper.vertMemoryRequirementsCombined.alignment; + alignmentPadding = alignmentPadding == 0 ? 0 : helper.vertMemoryRequirementsCombined.alignment - alignmentPadding; sizeIndex += alignmentPadding; bufferCI.size = sizeIndex; bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.indexBuffer); - vkBindBufferMemory(vkDevice, grBinds.indexBuffer, et.deviceMemoryVert, offsetIndex); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->indexBuffer); + vkBindBufferMemory(vkDevice, etdHelper.grBinds->indexBuffer, helper.et.deviceMemoryVert, offsetIndex); runningOffset += sizeIndex; + // index += 1; - assert(runningOffset == combinedMemReqs.size); - const Asset *modelBinAsset = AM_Get(modelBinHandle); + assert(runningOffset == helper.vertMemoryRequirementsCombined.size); // create transfer items && transfer { VkDeviceMemory transferDeviceMemory; VkBuffer transferBuffer; void *data; - BeginTransferBuffer(combinedMemReqs.size, transferBuffer, transferDeviceMemory, data); - memset(data, '\0', combinedMemReqs.size); + BeginTransferBuffer(helper.vertMemoryRequirementsCombined.size, transferBuffer, transferDeviceMemory, data); + memset(data, '\0', helper.vertMemoryRequirementsCombined.size); char *dstPtr = nullptr; char *srcPtr = nullptr; dstPtr = static_cast<char *>(data) + offsetVert; - srcPtr = static_cast<char *>(modelBinAsset->ptr) + accVert.buffer_view->offset; + srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accVert.buffer_view->offset; memcpy(dstPtr, srcPtr, accVert.buffer_view->size); dstPtr = static_cast<char *>(data) + offsetNorm; - srcPtr = static_cast<char *>(modelBinAsset->ptr) + accNorm.buffer_view->offset; + srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accNorm.buffer_view->offset; memcpy(dstPtr, srcPtr, accNorm.buffer_view->size); dstPtr = static_cast<char *>(data) + offsetUV; - srcPtr = static_cast<char *>(modelBinAsset->ptr) + accUV.buffer_view->offset; + srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accUV.buffer_view->offset; memcpy(dstPtr, srcPtr, accUV.buffer_view->size); dstPtr = static_cast<char *>(data) + offsetIndex; - srcPtr = static_cast<char *>(modelBinAsset->ptr) + accIndex.buffer_view->offset; + srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accIndex.buffer_view->offset; memcpy(dstPtr, srcPtr, accIndex.buffer_view->size); VkCommandBufferBeginInfo vkCommandBufferBeginInfo; @@ -591,22 +756,22 @@ void EntityType_Load(EntityType &et) { index = 0; bufferCopys[index].srcOffset = offsetVert; bufferCopys[index].size = sizeVert; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.vertexBuffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->vertexBuffer, 1, &bufferCopys[index]); index+=1; bufferCopys[index].srcOffset = offsetNorm; bufferCopys[index].size = sizeNorm; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.normalsBuffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->normalsBuffer, 1, &bufferCopys[index]); index+=1; bufferCopys[index].srcOffset = offsetUV; bufferCopys[index].size = sizeUV; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.uvBuffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->uvBuffer, 1, &bufferCopys[index]); index+=1; bufferCopys[index].srcOffset = offsetIndex; bufferCopys[index].size = sizeIndex; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.indexBuffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->indexBuffer, 1, &bufferCopys[index]); // index+=1; vkEndCommandBuffer(transferCommandBuffer); @@ -628,186 +793,111 @@ void EntityType_Load(EntityType &et) { } // set up instance buffer - grBinds.instanceBufferMaxCount = et.startingInstanceCount; - grBinds.instanceBufferMaxCount = grBinds.instanceBufferMaxCount < 1 ? 1 : grBinds.instanceBufferMaxCount; - bufferCI.size = sizeof(glm::mat4) * grBinds.instanceBufferMaxCount; + etdHelper.grBinds->instanceBufferMaxCount = etdHelper.etd->startingInstanceCount; + etdHelper.grBinds->instanceBufferMaxCount = etdHelper.grBinds->instanceBufferMaxCount < 1 ? 1 : etdHelper.grBinds->instanceBufferMaxCount; + bufferCI.size = sizeof(glm::mat4) * etdHelper.grBinds->instanceBufferMaxCount; bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_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, &et.deviceMemoryInst); - vkBindBufferMemory(vkDevice, grBinds.instanceBuffer, et.deviceMemoryInst, 0); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->instanceBuffer); + vkBindBufferMemory(vkDevice, etdHelper.grBinds->instanceBuffer, helper.et.deviceMemoryInst, 0); // bullet - btConvexHullShape *shape; - { - shape = Pke_New<btConvexHullShape>(MemBkt_Bullet); - btScalar *vertDataPointer = reinterpret_cast<btScalar *>(modelBinAsset->ptr); - vertDataPointer += accVert.buffer_view->offset; - new (shape) btConvexHullShape(vertDataPointer, accVert.count, accVert.stride); - shape->optimizeConvexHull(); - shape->initializePolyhedralFeatures(); - et.bt.shape = shape; - } - assert(shape != nullptr); - - modelBinAsset = CAFE_BABE(Asset); - AM_Release(modelBinHandle); // 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[4]; - for (long i = 0; i < 4; ++i) { - physBufferCI[i].sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - physBufferCI[i].pNext = nullptr; - physBufferCI[i].flags = {}; - physBufferCI[i].sharingMode = VK_SHARING_MODE_EXCLUSIVE; - physBufferCI[i].queueFamilyIndexCount = 1; - physBufferCI[i].pQueueFamilyIndices = &graphicsFamilyIndex; - } - - VkMemoryRequirements memReqs[4]; + index = 0; + runningOffset = 0; // vertex - index = 0; - physBufferCI[index].size = sizeof(glm::vec3) * vertexes.Count(); - physBufferCI[index].usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &physBufferCI[index], vkAllocator, &grBinds.physVertBD.buffer); - vkGetBufferMemoryRequirements(vkDevice, grBinds.physVertBD.buffer, &memReqs[index]); - grBinds.physVertBD.bindingCount = vertexes.Count(); - grBinds.physVertBD.firstBinding = index; + offsetVert = runningOffset; + sizeVert = sizeof(glm::vec3) * etdHelper.physDbg.vertexes->Count(); + etdHelper.grBinds->physVertBD.firstBinding = index; + etdHelper.grBinds->physVertBD.bindingCount = 1; + alignmentPadding = sizeVert % helper.physVertMemoryRequirementsCombined.alignment; + alignmentPadding = alignmentPadding == 0 ? 0 : helper.physVertMemoryRequirementsCombined.alignment - alignmentPadding; + sizeVert += alignmentPadding; + bufferCI.size = sizeVert; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->physVertBD.buffer); + vkBindBufferMemory(vkDevice, etdHelper.grBinds->physVertBD.buffer, helper.et.deviceMemoryPhysVert, offsetVert); + runningOffset += sizeVert; // norm index = 1; - physBufferCI[index].size = sizeof(glm::vec3) * normals.Count(); - physBufferCI[index].usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &physBufferCI[index], vkAllocator, &grBinds.physNormBD.buffer); - vkGetBufferMemoryRequirements(vkDevice, grBinds.physNormBD.buffer, &memReqs[index]); - grBinds.physNormBD.bindingCount = normals.Count(); - grBinds.physNormBD.firstBinding = index; + offsetNorm = runningOffset; + sizeNorm = sizeof(glm::vec3) * etdHelper.physDbg.normals->Count(); + etdHelper.grBinds->physNormBD.firstBinding = index; + etdHelper.grBinds->physNormBD.bindingCount = 1; + alignmentPadding = sizeNorm % helper.physVertMemoryRequirementsCombined.alignment; + alignmentPadding = alignmentPadding == 0 ? 0 : helper.physVertMemoryRequirementsCombined.alignment - alignmentPadding; + sizeNorm += alignmentPadding; + bufferCI.size = sizeNorm; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->physNormBD.buffer); + vkBindBufferMemory(vkDevice, etdHelper.grBinds->physNormBD.buffer, helper.et.deviceMemoryPhysVert, offsetNorm); + runningOffset += sizeNorm; // uv index = 2; - physBufferCI[index].size = sizeof(glm::vec2) * uv.Count(); - physBufferCI[index].usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &physBufferCI[index], vkAllocator, &grBinds.physUvBD.buffer); - vkGetBufferMemoryRequirements(vkDevice, grBinds.physUvBD.buffer, &memReqs[index]); - grBinds.physUvBD.bindingCount = uv.Count(); - grBinds.physUvBD.firstBinding = index; - - // index - index = 3; - physBufferCI[index].size = sizeof(uint16_t) * indexes.Count(); - physBufferCI[index].usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &physBufferCI[index], vkAllocator, &grBinds.physIndxBD.buffer); - vkGetBufferMemoryRequirements(vkDevice, grBinds.physIndxBD.buffer, &memReqs[index]); - grBinds.physIndxBD.bindingCount = indexes.Count(); - // grBinds.physIndxBD.firstBinding = index; + offsetUV = runningOffset; + sizeUV = sizeof(glm::vec2) * etdHelper.physDbg.uv->Count(); + etdHelper.grBinds->physUvBD.firstBinding = index; + etdHelper.grBinds->physUvBD.bindingCount = 1; + alignmentPadding = sizeUV % helper.physVertMemoryRequirementsCombined.alignment; + alignmentPadding = alignmentPadding == 0 ? 0 : helper.physVertMemoryRequirementsCombined.alignment - alignmentPadding; + sizeUV += alignmentPadding; + bufferCI.size = sizeUV; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->physUvBD.buffer); + vkBindBufferMemory(vkDevice, etdHelper.grBinds->physUvBD.buffer, helper.et.deviceMemoryPhysVert, offsetUV); + runningOffset += sizeUV; - CalculateCombinedMemReqs(4, memReqs, combinedMemReqs); - - // vert - index = 0; - if (memReqs[index].size != physBufferCI[index].size) { - vkDestroyBuffer(vkDevice, grBinds.physVertBD.buffer, vkAllocator); - physBufferCI[index].size = memReqs[index].size; - vkCreateBuffer(vkDevice, &physBufferCI[index], vkAllocator, &grBinds.physVertBD.buffer); - } - // norm - index = 1; - if (memReqs[index].size != physBufferCI[index].size) { - vkDestroyBuffer(vkDevice, grBinds.physNormBD.buffer, vkAllocator); - physBufferCI[index].size = memReqs[index].size; - vkCreateBuffer(vkDevice, &physBufferCI[index], vkAllocator, &grBinds.physNormBD.buffer); - } - // uv - index = 2; - if (memReqs[index].size != physBufferCI[index].size) { - vkDestroyBuffer(vkDevice, grBinds.physUvBD.buffer, vkAllocator); - physBufferCI[index].size = memReqs[index].size; - vkCreateBuffer(vkDevice, &physBufferCI[index], vkAllocator, &grBinds.physUvBD.buffer); - } // index index = 3; - if (memReqs[index].size != physBufferCI[index].size) { - vkDestroyBuffer(vkDevice, grBinds.physIndxBD.buffer, vkAllocator); - physBufferCI[index].size = memReqs[index].size; - vkCreateBuffer(vkDevice, &physBufferCI[index], vkAllocator, &grBinds.physIndxBD.buffer); - } - - // 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); + offsetIndex = runningOffset; + sizeIndex = sizeof(uint16_t) * etdHelper.physDbg.indexes->Count(); + etdHelper.grBinds->physIndxBD.firstBinding = index; + etdHelper.grBinds->physIndxBD.bindingCount = 1; + alignmentPadding = sizeIndex % helper.physVertMemoryRequirementsCombined.alignment; + alignmentPadding = alignmentPadding == 0 ? 0 : helper.physVertMemoryRequirementsCombined.alignment - alignmentPadding; + sizeIndex += alignmentPadding; + bufferCI.size = sizeIndex; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->physIndxBD.buffer); + vkBindBufferMemory(vkDevice, etdHelper.grBinds->physIndxBD.buffer, helper.et.deviceMemoryPhysVert, offsetIndex); + runningOffset += sizeIndex; + + assert(runningOffset == helper.physVertMemoryRequirementsCombined.size); // create transfer items && transfer { VkDeviceMemory transferDeviceMemory; VkBuffer transferBuffer; void *data; - BeginTransferBuffer(combinedMemReqs.size, transferBuffer, transferDeviceMemory, data); - memset(data, '\0', combinedMemReqs.size); + BeginTransferBuffer(helper.physVertMemoryRequirementsCombined.size, transferBuffer, transferDeviceMemory, data); + memset(data, '\0', helper.physVertMemoryRequirementsCombined.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; + srcPtr = reinterpret_cast<char *>(etdHelper.physDbg.vertexes->GetPtr()); + memcpy(dstPtr, srcPtr, sizeVert); + runningOffset += sizeVert; dstPtr = static_cast<char *>(data) + runningOffset; - srcPtr = reinterpret_cast<char *>(normals.GetPtr()); - memcpy(dstPtr, srcPtr, sizeof(glm::vec3) * normals.Count()); - runningOffset += memReqs[1].size; + srcPtr = reinterpret_cast<char *>(etdHelper.physDbg.normals->GetPtr()); + memcpy(dstPtr, srcPtr, sizeNorm); + runningOffset += sizeNorm; dstPtr = static_cast<char *>(data) + runningOffset; - srcPtr = reinterpret_cast<char *>(uv.GetPtr()); - memcpy(dstPtr, srcPtr, sizeof(glm::vec2) * uv.Count()); - runningOffset += memReqs[2].size; + srcPtr = reinterpret_cast<char *>(etdHelper.physDbg.uv->GetPtr()); + memcpy(dstPtr, srcPtr, sizeUV); + runningOffset += sizeUV; dstPtr = static_cast<char *>(data) + runningOffset; - srcPtr = reinterpret_cast<char *>(indexes.GetPtr()); - memcpy(dstPtr, srcPtr, sizeof(uint16_t) * indexes.Count()); + srcPtr = reinterpret_cast<char *>(etdHelper.physDbg.indexes->GetPtr()); + memcpy(dstPtr, srcPtr, sizeIndex); VkCommandBufferBeginInfo vkCommandBufferBeginInfo; vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -823,27 +913,27 @@ void EntityType_Load(EntityType &et) { 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; + bufferCopys[index].size = sizeVert; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->physVertBD.buffer, 1, &bufferCopys[index]); + runningOffset += sizeVert; 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; + bufferCopys[index].size = sizeNorm; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->physNormBD.buffer, 1, &bufferCopys[index]); + runningOffset += sizeNorm; 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; + bufferCopys[index].size = sizeUV; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->physUvBD.buffer, 1, &bufferCopys[index]); + runningOffset += sizeUV; 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; + bufferCopys[index].size = sizeIndex; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->physIndxBD.buffer, 1, &bufferCopys[index]); + // runningOffset += sizeIndex; // index+=1; vkEndCommandBuffer(transferCommandBuffer); @@ -864,18 +954,88 @@ void EntityType_Load(EntityType &et) { EndTransferBuffer(transferBuffer, transferDeviceMemory); } } +} + +void EntityType_Load(EntityType &et) { + AssetHandle assetHandle{AM_GetHandle(et.modelAssetKey)}; + assert(assetHandle != AssetHandle_MAX); + + const Asset *asset = AM_Get(assetHandle); + cgltf_options options{}; + // TODO allocator + cgltf_data *gltfData = nullptr; + cgltf_result result = cgltf_parse(&options, asset->ptr, asset->size, &gltfData); + assert(result == cgltf_result_success); + result = cgltf_validate(gltfData); + assert(result == cgltf_result_success); + assert(gltfData->buffers_count == 1); + + // 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); + } + + std::filesystem::path gltfPath{asset->basePath}; + gltfPath.replace_filename(gltfData->buffers[0].uri); + AssetHandle modelBinHandle = AM_Register(gltfPath.c_str(), PKE_ASSET_TYPE_UNSET); + + const Asset *modelBinAsset = AM_Get(modelBinHandle); + MemBucket *entLoaderBkt = Pke_BeginTransientBucket(); + EntityType_LoadHelperStruct helper { + .bkt = entLoaderBkt, + .et = et, + .etdHelpers = reinterpret_cast<DynArray<EntityTypeDetails_LoadHelperStruct> *>(Pke_New(sizeof(DynArray<EntityTypeDetails_LoadHelperStruct>), 64, entLoaderBkt)), + .gltfData = gltfData, + .modelBinAsset = modelBinAsset, + .vertMemoryRequirements = reinterpret_cast<DynArray<VkMemoryRequirements> *>(Pke_New(sizeof(DynArray<VkMemoryRequirements>), 64, entLoaderBkt)), + .instMemoryRequirements = reinterpret_cast<DynArray<VkMemoryRequirements> *>(Pke_New(sizeof(DynArray<VkMemoryRequirements>), 64, entLoaderBkt)), + .physVertMemoryRequirements = reinterpret_cast<DynArray<VkMemoryRequirements> *>(Pke_New(sizeof(DynArray<VkMemoryRequirements>), 64, entLoaderBkt)), + .textureMemoryRequirements = reinterpret_cast<DynArray<VkMemoryRequirements> *>(Pke_New(sizeof(DynArray<VkMemoryRequirements>), 64, entLoaderBkt)), + }; + new (helper.etdHelpers) DynArray<EntityTypeDetails_LoadHelperStruct>{entLoaderBkt}; + new (helper.vertMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; + new (helper.instMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; + new (helper.physVertMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; + new (helper.textureMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; + + EntityType_PreLoad(helper); + + for (int64_t i = 0; i < et.detailsCount; ++i) { + EntityTypeDetails_LoadHelperStruct &etd = (*helper.etdHelpers)[i]; + /* + * 2023-09-13 - JCB + * I don't like that we're just copying this. + * This should be moved to window.cpp. + */ + etd.grBinds->vkPipelineLayout = pkePipelines.vkPipelineLayout_Texture; + etd.grBinds->graphicsPipeline = pkePipelines.pipelines.Texture; + + // handle texture + EntityType_LoadTexture(helper, i); + + //handle mesh + EntityType_LoadMesh(helper, i); + } + + // TODO DeviceMemory // cleanup - // cgltf_free(gltfData); + AM_Release(modelBinHandle); AM_Release(assetHandle); + Pke_EndTransientBucket(helper.bkt); } void EntityType_Tick_Late(double delta) { while (EntitiesWithExcessInstances.Count() != 0) { auto entHandle = EntitiesWithExcessInstances.Pop(); - auto index = EntityType_FindByEntityHandle(entHandle); + int64_t detailIndex = 0; + auto index = EntityType_FindByEntityHandle(entHandle, detailIndex); auto &et = GlobalEntityTypes[index]; - auto &grBinds = *ECS_GetGrBinds(entHandle); + auto &etd = GlobalEntityTypes[index].details[detailIndex]; + auto &grBinds = *ECS_GetGrBinds(etd.entityHandle); EntityType_RolloverInstances(et, grBinds); } } @@ -980,40 +1140,47 @@ void EntityType_Teardown() { long entityTypeCount = GlobalEntityTypes.Count(); for (long i = 0; i < entityTypeCount; ++i) { if (GlobalEntityTypes[i].modelAssetKey[0] == '\0') continue; - auto *et = &GlobalEntityTypes[i]; - auto *grBinds = ECS_GetGrBinds(GlobalEntityTypes[i].entityHandle); - if (grBinds->vkDescriptorSets != nullptr && et->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, et->vkDescriptorPool, vkAllocator); - Pke_Delete<VkDescriptorSet>(grBinds->vkDescriptorSets, MAX_FRAMES_IN_FLIGHT); + 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); + } - 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 (et->textureImageView != VK_NULL_HANDLE) - vkDestroyImageView(vkDevice, et->textureImageView, vkAllocator); - if (et->textureImage != VK_NULL_HANDLE) - vkDestroyImage(vkDevice, et->textureImage, vkAllocator); if (et->deviceMemoryInst != VK_NULL_HANDLE) vkFreeMemory(vkDevice, et->deviceMemoryInst, vkAllocator); if (et->deviceMemoryVert != VK_NULL_HANDLE) |
