summaryrefslogtreecommitdiff
path: root/src/entities.cpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2024-01-02 14:01:44 -0500
committerJonathan Bradley <jcb@pikum.xyz>2024-01-02 14:01:44 -0500
commitbe543940e3c561ee2ab8eb315211112b97065476 (patch)
treeabbf4968dab73b7d242d3052904e5b2e2c854d82 /src/entities.cpp
parent0b9c784570fe3660b238b537fa7ba7e5de8783aa (diff)
factor out loading entity textures for reuse
Diffstat (limited to 'src/entities.cpp')
-rw-r--r--src/entities.cpp1427
1 files changed, 715 insertions, 712 deletions
diff --git a/src/entities.cpp b/src/entities.cpp
index ab4f731..ad72b04 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -71,480 +71,712 @@ void CalculateCombinedMemReqs(uint64_t memReqsCount, VkMemoryRequirements *memRe
}
}
+void EntityType_LoadTexture(EntityType &et, CompGrBinds &grBinds, AssetHandle textureAssetHandle) {
+ 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);
+ assert(pixels != nullptr && "sbti_load failed to load image.");
+ } else {
+ pixelWidth = 2;
+ pixelHeight = 2;
+ pixelChannels = 4;
+ pixels = const_cast<unsigned char *>(&PKE_MISSING_TEXTURE_DATA[0]);
+ }
+
+ uint32_t imageSizeBytes = pixelWidth * pixelHeight * pixelChannels;
+
+ 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 vkImageCreateInfo;
+ vkImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ vkImageCreateInfo.pNext = nullptr;
+ vkImageCreateInfo.flags = 0;
+ vkImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
+ vkImageCreateInfo.format = imageFormat;
+ vkImageCreateInfo.extent = VkExtent3D {
+ .width = static_cast<uint32_t>(pixelWidth),
+ .height = static_cast<uint32_t>(pixelHeight),
+ .depth = 1
+ };
+ 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;
+
+ 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);
+
+ VkImageViewCreateInfo vkImageViewCreateInfo;
+ vkImageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ vkImageViewCreateInfo.pNext = nullptr;
+ vkImageViewCreateInfo.flags = 0;
+ vkImageViewCreateInfo.image = et.textureImage;
+ // TODO animated textures
+ vkImageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ vkImageViewCreateInfo.format = imageFormat;
+ vkImageViewCreateInfo.components = VkComponentMapping {
+ .r = VK_COMPONENT_SWIZZLE_IDENTITY,
+ .g = VK_COMPONENT_SWIZZLE_IDENTITY,
+ .b = VK_COMPONENT_SWIZZLE_IDENTITY,
+ .a = VK_COMPONENT_SWIZZLE_IDENTITY,
+ };
+ vkImageViewCreateInfo.subresourceRange = VkImageSubresourceRange {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ // TODO MapMap
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ // TODO animated textures
+ .layerCount = 1,
+ };
+
+ vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &et.textureImageView);
+
+ // transition image layout and copy to buffer
+ VkBuffer transferImageBuffer;
+ VkDeviceMemory transferImageMemory;
+ void *deviceData;
+ BeginTransferBuffer(imageSizeBytes, transferImageBuffer, transferImageMemory, deviceData);
+ memcpy(deviceData, pixels, imageSizeBytes);
+ {
+ VkImageMemoryBarrier vkImageMemoryBarrier;
+ vkImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ vkImageMemoryBarrier.pNext = nullptr;
+ vkImageMemoryBarrier.srcAccessMask = {};
+ vkImageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ vkImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ 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.subresourceRange = VkImageSubresourceRange {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ // TODO MipMap
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ // TODO animated textures
+ .layerCount = 1,
+ };
+
+ VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
+ vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ vkCommandBufferBeginInfo.pNext = nullptr;
+ vkCommandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
+
+ vkBeginCommandBuffer(transferCommandBuffer, &vkCommandBufferBeginInfo);
+
+ vkCmdPipelineBarrier(transferCommandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &vkImageMemoryBarrier);
+
+ // TODO animated textures / texture array - make this an array
+ VkBufferImageCopy vkBufferImageCopy;
+ vkBufferImageCopy.bufferOffset = 0;
+ vkBufferImageCopy.bufferRowLength = pixelWidth;
+ vkBufferImageCopy.bufferImageHeight = pixelHeight;
+ vkBufferImageCopy.imageSubresource = VkImageSubresourceLayers {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .mipLevel = 0,
+ // TODO animated textures
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ };
+ vkBufferImageCopy.imageOffset = VkOffset3D {
+ .x = 0,
+ .y = 0,
+ .z = 0,
+ };
+ vkBufferImageCopy.imageExtent = VkExtent3D {
+ .width = static_cast<uint32_t>(pixelWidth),
+ .height = static_cast<uint32_t>(pixelHeight),
+ .depth = 1,
+ };
+ vkCmdCopyBufferToImage(transferCommandBuffer, transferImageBuffer, et.textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vkBufferImageCopy);
+
+ 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);
+ vkResetCommandBuffer(transferCommandBuffer, 0);
+ }
+ EndTransferBuffer(transferImageBuffer, transferImageMemory);
+ {
+ VkImageMemoryBarrier vkImageMemoryBarrier;
+ vkImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ vkImageMemoryBarrier.pNext = nullptr;
+ vkImageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ vkImageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ vkImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ 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.subresourceRange = VkImageSubresourceRange {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ // TODO MipMap
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ // TODO animated textures
+ .layerCount = 1,
+ };
+
+ VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
+ vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ vkCommandBufferBeginInfo.pNext = nullptr;
+ vkCommandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
+
+ vkBeginCommandBuffer(graphicsCommandBuffer, &vkCommandBufferBeginInfo);
+
+ vkCmdPipelineBarrier(graphicsCommandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &vkImageMemoryBarrier);
+
+ vkEndCommandBuffer(graphicsCommandBuffer);
+
+ 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 = &graphicsCommandBuffer;
+ submitInfo.signalSemaphoreCount = 0;
+ submitInfo.pSignalSemaphores = nullptr;
+ vkQueueSubmit(graphicsQueue, 1, &submitInfo, nullptr);
+ vkQueueWaitIdle(graphicsQueue);
+ }
+
+ // TODO double-check this?
+ // stbi_image_free(pixels);
+ if (textureAssetHandle != AssetHandle_MAX) {
+ AM_Release(textureAssetHandle);
+ }
+
+ // descriptor pool & sets
+
+ VkDescriptorPoolSize descriptorPoolSizes[2];
+ descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ descriptorPoolSizes[0].descriptorCount = MAX_FRAMES_IN_FLIGHT;
+ descriptorPoolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ descriptorPoolSizes[1].descriptorCount = MAX_FRAMES_IN_FLIGHT;
+
+ VkDescriptorPoolCreateInfo vkDescriptorPoolCreateInfo;
+ vkDescriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+ vkDescriptorPoolCreateInfo.pNext = nullptr;
+ vkDescriptorPoolCreateInfo.flags = 0;
+ vkDescriptorPoolCreateInfo.maxSets = MAX_FRAMES_IN_FLIGHT;
+ vkDescriptorPoolCreateInfo.poolSizeCount = (uint32_t)2;
+ vkDescriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes;
+
+ // consider making me a global pool
+ auto vkResult = vkCreateDescriptorPool(vkDevice, &vkDescriptorPoolCreateInfo, vkAllocator, &et.vkDescriptorPool);
+ assert(vkResult == VK_SUCCESS);
+
+ VkDescriptorSetLayout descriptorSets[MAX_FRAMES_IN_FLIGHT];
+ for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
+ descriptorSets[i] = pkePipelines.vkDescriptorSetLayout_Texture;
+ }
+ VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo;
+ vkDescriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ vkDescriptorSetAllocateInfo.pNext = nullptr;
+ vkDescriptorSetAllocateInfo.descriptorPool = et.vkDescriptorPool;
+ vkDescriptorSetAllocateInfo.descriptorSetCount = MAX_FRAMES_IN_FLIGHT;
+ vkDescriptorSetAllocateInfo.pSetLayouts = descriptorSets;
+
+ grBinds.vkDescriptorSets = Pke_New<VkDescriptorSet>(MAX_FRAMES_IN_FLIGHT);
+ for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
+ grBinds.vkDescriptorSets[i] = VkDescriptorSet{};
+ }
+ vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, grBinds.vkDescriptorSets);
+ assert(vkResult == VK_SUCCESS);
+
+ VkWriteDescriptorSet writeDescriptorSets[2 * MAX_FRAMES_IN_FLIGHT];
+ for (long i = 0; i < 2 * MAX_FRAMES_IN_FLIGHT; ++i) {
+ writeDescriptorSets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ writeDescriptorSets[i].pNext = nullptr;
+ writeDescriptorSets[i].dstSet = nullptr;
+ writeDescriptorSets[i].dstBinding = i % 2;
+ writeDescriptorSets[i].dstArrayElement = 0;
+ writeDescriptorSets[i].descriptorCount = 1;
+ writeDescriptorSets[i].descriptorType = (i % 2) == 0
+ ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ writeDescriptorSets[i].pImageInfo = nullptr;
+ writeDescriptorSets[i].pBufferInfo = nullptr;
+ writeDescriptorSets[i].pTexelBufferView = nullptr;
+ }
+
+ VkDescriptorImageInfo textureDescriptorInfo;
+ textureDescriptorInfo.sampler = pkePipelines.vkSampler_Texture;
+ textureDescriptorInfo.imageView = et.textureImageView;
+ textureDescriptorInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+ VkDescriptorBufferInfo vkDescriptorBufferInfo[MAX_FRAMES_IN_FLIGHT];
+
+ for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
+ vkDescriptorBufferInfo[i].buffer = UniformBuffers[i];
+ vkDescriptorBufferInfo[i].offset = 0;
+ vkDescriptorBufferInfo[i].range = sizeof(UniformBufferObject);
+
+ long uboIndex = i * 2;
+ long samplerIndex = uboIndex + 1;
+
+ writeDescriptorSets[uboIndex].pBufferInfo = &vkDescriptorBufferInfo[i];
+ writeDescriptorSets[uboIndex].dstSet = grBinds.vkDescriptorSets[i];
+
+ writeDescriptorSets[samplerIndex].pImageInfo = &textureDescriptorInfo;
+ writeDescriptorSets[samplerIndex].dstSet = 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)};
- if (assetHandle != AssetHandle_MAX) {
- const Asset *asset = AM_Get(assetHandle);
-
- 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;
-
- 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);
-
- std::filesystem::path gltfPath{asset->basePath};
- gltfPath.replace_filename(gltfData->buffers[0].uri);
- AssetHandle modelBinHandle = AM_Register(gltfPath.c_str(), PKE_ASSET_TYPE_UNSET);
-
- int 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);
- assert(pixels != nullptr && "sbti_load failed to load image.");
- } else {
- pixelWidth = 2;
- pixelHeight = 2;
- pixelChannels = 4;
- pixels = const_cast<unsigned char *>(&PKE_MISSING_TEXTURE_DATA[0]);
- }
+ EntityType_LoadTexture(et, grBinds, textureAssetHandle);
+
+ //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);
+
+ std::filesystem::path gltfPath{asset->basePath};
+ gltfPath.replace_filename(gltfData->buffers[0].uri);
+ AssetHandle modelBinHandle = AM_Register(gltfPath.c_str(), PKE_ASSET_TYPE_UNSET);
+
+ // 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);
+
+ 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;
+
+ 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;
+
+ // vertex
+ uint32_t offsetVert = runningOffset;
+ uint32_t sizeVert = accVert.buffer_view->size;
+ alignmentPadding = sizeVert % combinedMemReqs.alignment;
+ alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.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);
+ runningOffset += sizeVert;
+
+ // norm
+ uint32_t offsetNorm = runningOffset;
+ uint32_t sizeNorm = accNorm.buffer_view->size;
+ alignmentPadding = sizeNorm % combinedMemReqs.alignment;
+ alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding;
+ sizeNorm += alignmentPadding;
+ bufferCI.size = sizeNorm;
+ vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.normalsBuffer);
+ vkBindBufferMemory(vkDevice, grBinds.normalsBuffer, et.deviceMemoryVert, offsetNorm);
+ runningOffset += sizeNorm;
+
+ // uv
+ uint32_t offsetUV = runningOffset;
+ uint32_t sizeUV = accUV.buffer_view->size;
+ alignmentPadding = sizeUV % combinedMemReqs.alignment;
+ alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding;
+ sizeUV += alignmentPadding;
+ bufferCI.size = sizeUV;
+ vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.uvBuffer);
+ vkBindBufferMemory(vkDevice, grBinds.uvBuffer , et.deviceMemoryVert, offsetUV);
+ runningOffset += sizeUV;
+
+ // index
+ uint32_t offsetIndex = runningOffset;
+ uint32_t sizeIndex = accIndex.buffer_view->size;
+ alignmentPadding = sizeIndex % combinedMemReqs.alignment;
+ alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.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);
+ runningOffset += sizeIndex;
+
+ assert(runningOffset == combinedMemReqs.size);
+ const Asset *modelBinAsset = AM_Get(modelBinHandle);
+
+ // create transfer items && transfer
+ {
+ VkDeviceMemory transferDeviceMemory;
+ VkBuffer transferBuffer;
+ void *data;
+ BeginTransferBuffer(combinedMemReqs.size, transferBuffer, transferDeviceMemory, data);
+ memset(data, '\0', combinedMemReqs.size);
- {
- uint32_t imageSizeBytes = pixelWidth * pixelHeight * pixelChannels;
-
- 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);
- }
+ char *dstPtr = nullptr;
+ char *srcPtr = nullptr;
- VkImageCreateInfo vkImageCreateInfo;
- vkImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
- vkImageCreateInfo.pNext = nullptr;
- vkImageCreateInfo.flags = 0;
- vkImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
- vkImageCreateInfo.format = imageFormat;
- vkImageCreateInfo.extent = VkExtent3D {
- .width = static_cast<uint32_t>(pixelWidth),
- .height = static_cast<uint32_t>(pixelHeight),
- .depth = 1
- };
- 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;
-
- 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);
-
- VkImageViewCreateInfo vkImageViewCreateInfo;
- vkImageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
- vkImageViewCreateInfo.pNext = nullptr;
- vkImageViewCreateInfo.flags = 0;
- vkImageViewCreateInfo.image = et.textureImage;
- // TODO animated textures
- vkImageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
- vkImageViewCreateInfo.format = imageFormat;
- vkImageViewCreateInfo.components = VkComponentMapping {
- .r = VK_COMPONENT_SWIZZLE_IDENTITY,
- .g = VK_COMPONENT_SWIZZLE_IDENTITY,
- .b = VK_COMPONENT_SWIZZLE_IDENTITY,
- .a = VK_COMPONENT_SWIZZLE_IDENTITY,
- };
- vkImageViewCreateInfo.subresourceRange = VkImageSubresourceRange {
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .baseMipLevel = 0,
- // TODO MapMap
- .levelCount = 1,
- .baseArrayLayer = 0,
- // TODO animated textures
- .layerCount = 1,
- };
-
- vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &et.textureImageView);
-
- // transition image layout and copy to buffer
- VkBuffer transferImageBuffer;
- VkDeviceMemory transferImageMemory;
- void *deviceData;
- BeginTransferBuffer(imageSizeBytes, transferImageBuffer, transferImageMemory, deviceData);
- memcpy(deviceData, pixels, imageSizeBytes);
- {
- VkImageMemoryBarrier vkImageMemoryBarrier;
- vkImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- vkImageMemoryBarrier.pNext = nullptr;
- vkImageMemoryBarrier.srcAccessMask = {};
- vkImageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- vkImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- 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.subresourceRange = VkImageSubresourceRange {
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .baseMipLevel = 0,
- // TODO MipMap
- .levelCount = 1,
- .baseArrayLayer = 0,
- // TODO animated textures
- .layerCount = 1,
- };
-
- VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
- vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- vkCommandBufferBeginInfo.pNext = nullptr;
- vkCommandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
-
- vkBeginCommandBuffer(transferCommandBuffer, &vkCommandBufferBeginInfo);
-
- vkCmdPipelineBarrier(transferCommandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &vkImageMemoryBarrier);
-
- // TODO animated textures / texture array - make this an array
- VkBufferImageCopy vkBufferImageCopy;
- vkBufferImageCopy.bufferOffset = 0;
- vkBufferImageCopy.bufferRowLength = pixelWidth;
- vkBufferImageCopy.bufferImageHeight = pixelHeight;
- vkBufferImageCopy.imageSubresource = VkImageSubresourceLayers {
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .mipLevel = 0,
- // TODO animated textures
- .baseArrayLayer = 0,
- .layerCount = 1,
- };
- vkBufferImageCopy.imageOffset = VkOffset3D {
- .x = 0,
- .y = 0,
- .z = 0,
- };
- vkBufferImageCopy.imageExtent = VkExtent3D {
- .width = static_cast<uint32_t>(pixelWidth),
- .height = static_cast<uint32_t>(pixelHeight),
- .depth = 1,
- };
- vkCmdCopyBufferToImage(transferCommandBuffer, transferImageBuffer, et.textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vkBufferImageCopy);
-
- 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);
- vkResetCommandBuffer(transferCommandBuffer, 0);
- }
- EndTransferBuffer(transferImageBuffer, transferImageMemory);
- {
- VkImageMemoryBarrier vkImageMemoryBarrier;
- vkImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- vkImageMemoryBarrier.pNext = nullptr;
- vkImageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- vkImageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- vkImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
- 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.subresourceRange = VkImageSubresourceRange {
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .baseMipLevel = 0,
- // TODO MipMap
- .levelCount = 1,
- .baseArrayLayer = 0,
- // TODO animated textures
- .layerCount = 1,
- };
-
- VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
- vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- vkCommandBufferBeginInfo.pNext = nullptr;
- vkCommandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
-
- vkBeginCommandBuffer(graphicsCommandBuffer, &vkCommandBufferBeginInfo);
-
- vkCmdPipelineBarrier(graphicsCommandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &vkImageMemoryBarrier);
-
- vkEndCommandBuffer(graphicsCommandBuffer);
-
- 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 = &graphicsCommandBuffer;
- submitInfo.signalSemaphoreCount = 0;
- submitInfo.pSignalSemaphores = nullptr;
- vkQueueSubmit(graphicsQueue, 1, &submitInfo, nullptr);
- vkQueueWaitIdle(graphicsQueue);
- }
+ dstPtr = static_cast<char *>(data) + offsetVert;
+ srcPtr = static_cast<char *>(modelBinAsset->ptr) + accVert.buffer_view->offset;
+ memcpy(dstPtr, srcPtr, accVert.buffer_view->size);
- // TODO double-check this?
- // stbi_image_free(pixels);
- if (textureAssetHandle != AssetHandle_MAX) {
- AM_Release(textureAssetHandle);
- }
+ dstPtr = static_cast<char *>(data) + offsetNorm;
+ srcPtr = static_cast<char *>(modelBinAsset->ptr) + accNorm.buffer_view->offset;
+ memcpy(dstPtr, srcPtr, accNorm.buffer_view->size);
- // descriptor pool & sets
-
- VkDescriptorPoolSize descriptorPoolSizes[2];
- descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- descriptorPoolSizes[0].descriptorCount = MAX_FRAMES_IN_FLIGHT;
- descriptorPoolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- descriptorPoolSizes[1].descriptorCount = MAX_FRAMES_IN_FLIGHT;
-
- VkDescriptorPoolCreateInfo vkDescriptorPoolCreateInfo;
- vkDescriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
- vkDescriptorPoolCreateInfo.pNext = nullptr;
- vkDescriptorPoolCreateInfo.flags = 0;
- vkDescriptorPoolCreateInfo.maxSets = MAX_FRAMES_IN_FLIGHT;
- vkDescriptorPoolCreateInfo.poolSizeCount = (uint32_t)2;
- vkDescriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes;
-
- // consider making me a global pool
- auto vkResult = vkCreateDescriptorPool(vkDevice, &vkDescriptorPoolCreateInfo, vkAllocator, &et.vkDescriptorPool);
- assert(vkResult == VK_SUCCESS);
-
- VkDescriptorSetLayout descriptorSets[MAX_FRAMES_IN_FLIGHT];
- for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
- descriptorSets[i] = pkePipelines.vkDescriptorSetLayout_Texture;
- }
- VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo;
- vkDescriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
- vkDescriptorSetAllocateInfo.pNext = nullptr;
- vkDescriptorSetAllocateInfo.descriptorPool = et.vkDescriptorPool;
- vkDescriptorSetAllocateInfo.descriptorSetCount = MAX_FRAMES_IN_FLIGHT;
- vkDescriptorSetAllocateInfo.pSetLayouts = descriptorSets;
-
- grBinds.vkDescriptorSets = Pke_New<VkDescriptorSet>(MAX_FRAMES_IN_FLIGHT);
- for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
- grBinds.vkDescriptorSets[i] = VkDescriptorSet{};
- }
- vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, grBinds.vkDescriptorSets);
- assert(vkResult == VK_SUCCESS);
-
- VkWriteDescriptorSet writeDescriptorSets[2 * MAX_FRAMES_IN_FLIGHT];
- for (long i = 0; i < 2 * MAX_FRAMES_IN_FLIGHT; ++i) {
- writeDescriptorSets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- writeDescriptorSets[i].pNext = nullptr;
- writeDescriptorSets[i].dstSet = nullptr;
- writeDescriptorSets[i].dstBinding = i % 2;
- writeDescriptorSets[i].dstArrayElement = 0;
- writeDescriptorSets[i].descriptorCount = 1;
- writeDescriptorSets[i].descriptorType = (i % 2) == 0
- ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- writeDescriptorSets[i].pImageInfo = nullptr;
- writeDescriptorSets[i].pBufferInfo = nullptr;
- writeDescriptorSets[i].pTexelBufferView = nullptr;
- }
+ dstPtr = static_cast<char *>(data) + offsetUV;
+ srcPtr = static_cast<char *>(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;
+ memcpy(dstPtr, srcPtr, accIndex.buffer_view->size);
+
+ 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;
+ bufferCopys[index].srcOffset = offsetVert;
+ bufferCopys[index].size = sizeVert;
+ vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.vertexBuffer, 1, &bufferCopys[index]);
+ index+=1;
- VkDescriptorImageInfo textureDescriptorInfo;
- textureDescriptorInfo.sampler = pkePipelines.vkSampler_Texture;
- textureDescriptorInfo.imageView = et.textureImageView;
- textureDescriptorInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ bufferCopys[index].srcOffset = offsetNorm;
+ bufferCopys[index].size = sizeNorm;
+ vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.normalsBuffer, 1, &bufferCopys[index]);
+ index+=1;
- VkDescriptorBufferInfo vkDescriptorBufferInfo[MAX_FRAMES_IN_FLIGHT];
+ bufferCopys[index].srcOffset = offsetUV;
+ bufferCopys[index].size = sizeUV;
+ vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.uvBuffer, 1, &bufferCopys[index]);
+ index+=1;
- for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
- vkDescriptorBufferInfo[i].buffer = UniformBuffers[i];
- vkDescriptorBufferInfo[i].offset = 0;
- vkDescriptorBufferInfo[i].range = sizeof(UniformBufferObject);
+ bufferCopys[index].srcOffset = offsetIndex;
+ bufferCopys[index].size = sizeIndex;
+ vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.indexBuffer, 1, &bufferCopys[index]);
+ // index+=1;
- long uboIndex = i * 2;
- long samplerIndex = uboIndex + 1;
+ vkEndCommandBuffer(transferCommandBuffer);
- writeDescriptorSets[uboIndex].pBufferInfo = &vkDescriptorBufferInfo[i];
- writeDescriptorSets[uboIndex].dstSet = grBinds.vkDescriptorSets[i];
+ 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);
- writeDescriptorSets[samplerIndex].pImageInfo = &textureDescriptorInfo;
- writeDescriptorSets[samplerIndex].dstSet = grBinds.vkDescriptorSets[i];
- }
+ EndTransferBuffer(transferBuffer, transferDeviceMemory);
+ }
- vkUpdateDescriptorSets(vkDevice, 2 * MAX_FRAMES_IN_FLIGHT, writeDescriptorSets, 0, nullptr);
- }
+ // set up instance buffer
+ grBinds.instanceBufferMaxCount = et.startingInstanceCount;
+ grBinds.instanceBufferMaxCount = grBinds.instanceBufferMaxCount < 1 ? 1 : grBinds.instanceBufferMaxCount;
+ bufferCI.size = sizeof(glm::mat4) * 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);
+
+ // 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);
- // make sure cgltf can interpret our model
- for (long i = 0; i < gltfData->accessors_count; ++i) {
- assert(gltfData->accessors[i].type != cgltf_type_invalid);
+ // 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 < gltfData->buffers_count; ++i) {
- assert(gltfData->buffer_views[i].type != cgltf_buffer_view_type_invalid);
+ 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]);
+ }
}
- assert(et.Importer_GLTF.AccessorIndexVertex > -1);
- assert(et.Importer_GLTF.AccessorIndexNormal > -1);
- assert(et.Importer_GLTF.AccessorIndexUV > -1);
- assert(et.Importer_GLTF.AccessorIndexIndex > -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;
-
- 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.
+ 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;
+ }
- // 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;
+ VkMemoryRequirements memReqs[4];
// vertex
- uint32_t offsetVert = runningOffset;
- uint32_t sizeVert = accVert.buffer_view->size;
- alignmentPadding = sizeVert % combinedMemReqs.alignment;
- alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.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);
- runningOffset += sizeVert;
+ 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;
// norm
- uint32_t offsetNorm = runningOffset;
- uint32_t sizeNorm = accNorm.buffer_view->size;
- alignmentPadding = sizeNorm % combinedMemReqs.alignment;
- alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding;
- sizeNorm += alignmentPadding;
- bufferCI.size = sizeNorm;
- vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.normalsBuffer);
- vkBindBufferMemory(vkDevice, grBinds.normalsBuffer, et.deviceMemoryVert, offsetNorm);
- runningOffset += sizeNorm;
+ 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;
// uv
- uint32_t offsetUV = runningOffset;
- uint32_t sizeUV = accUV.buffer_view->size;
- alignmentPadding = sizeUV % combinedMemReqs.alignment;
- alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding;
- sizeUV += alignmentPadding;
- bufferCI.size = sizeUV;
- vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.uvBuffer);
- vkBindBufferMemory(vkDevice, grBinds.uvBuffer , et.deviceMemoryVert, offsetUV);
- runningOffset += sizeUV;
+ 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
- uint32_t offsetIndex = runningOffset;
- uint32_t sizeIndex = accIndex.buffer_view->size;
- alignmentPadding = sizeIndex % combinedMemReqs.alignment;
- alignmentPadding = alignmentPadding == 0 ? 0 : combinedMemReqs.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);
- runningOffset += sizeIndex;
-
- assert(runningOffset == combinedMemReqs.size);
- const Asset *modelBinAsset = AM_Get(modelBinHandle);
+ 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;
+
+ 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);
// create transfer items && transfer
{
@@ -553,25 +785,29 @@ void EntityType_Load(EntityType &et) {
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) + offsetVert;
- srcPtr = static_cast<char *>(modelBinAsset->ptr) + accVert.buffer_view->offset;
- memcpy(dstPtr, srcPtr, accVert.buffer_view->size);
+ 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) + offsetNorm;
- srcPtr = static_cast<char *>(modelBinAsset->ptr) + accNorm.buffer_view->offset;
- memcpy(dstPtr, srcPtr, accNorm.buffer_view->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) + offsetUV;
- srcPtr = static_cast<char *>(modelBinAsset->ptr) + accUV.buffer_view->offset;
- memcpy(dstPtr, srcPtr, accUV.buffer_view->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) + offsetIndex;
- srcPtr = static_cast<char *>(modelBinAsset->ptr) + accIndex.buffer_view->offset;
- memcpy(dstPtr, srcPtr, accIndex.buffer_view->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;
@@ -585,24 +821,29 @@ void EntityType_Load(EntityType &et) {
bufferCopys[i].dstOffset = 0;
}
index = 0;
- bufferCopys[index].srcOffset = offsetVert;
- bufferCopys[index].size = sizeVert;
- vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.vertexBuffer, 1, &bufferCopys[index]);
+ 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 = offsetNorm;
- bufferCopys[index].size = sizeNorm;
- vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.normalsBuffer, 1, &bufferCopys[index]);
+ 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 = offsetUV;
- bufferCopys[index].size = sizeUV;
- vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.uvBuffer, 1, &bufferCopys[index]);
+ 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 = offsetIndex;
- bufferCopys[index].size = sizeIndex;
- vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.indexBuffer, 1, &bufferCopys[index]);
+ 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);
@@ -622,249 +863,11 @@ void EntityType_Load(EntityType &et) {
EndTransferBuffer(transferBuffer, transferDeviceMemory);
}
-
- // set up instance buffer
- grBinds.instanceBufferMaxCount = et.startingInstanceCount;
- grBinds.instanceBufferMaxCount = grBinds.instanceBufferMaxCount < 1 ? 1 : grBinds.instanceBufferMaxCount;
- bufferCI.size = sizeof(glm::mat4) * 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);
-
- // 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];
-
- // 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;
-
- // 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;
-
- // 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;
-
- 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);
-
- // 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
- // cgltf_free(gltfData);
- AM_Release(assetHandle);
}
+
+ // cleanup
+ // cgltf_free(gltfData);
+ AM_Release(assetHandle);
}
void EntityType_Tick_Late(double delta) {