diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-09-14 19:24:43 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-09-14 19:41:41 -0400 |
| commit | 2eb22f8debec811cdea32ed7b8cf3ec98c752f7c (patch) | |
| tree | 2fb1181c8b1ab0c741db5d408fb9bffe9300f47e /src | |
| parent | d7ce568e2baacc68424eae4adbb98ac5b126af21 (diff) | |
Load model textures checkpoint.
Refactors some Vulkan items related to CompGrBinds and EntityTypes.
Adds some Vulkan globals related to textures.
Adds a number of placeholder items:
- Iffy use of setting Vulkan globals on instanced structs.
- Unimplemented and inaccurate shaders
- Iffy gltf sub-buffer logic (ignores vertex color data)
- MipMap TODOs
- TextureArray TODOs
Diffstat (limited to 'src')
| -rw-r--r-- | src/components.hpp | 6 | ||||
| -rw-r--r-- | src/entities.cpp | 412 | ||||
| -rw-r--r-- | src/entities.hpp | 8 | ||||
| -rw-r--r-- | src/window.cpp | 45 |
4 files changed, 424 insertions, 47 deletions
diff --git a/src/components.hpp b/src/components.hpp index ce5f0f2..76dd7fc 100644 --- a/src/components.hpp +++ b/src/components.hpp @@ -31,8 +31,8 @@ struct InstPos { struct CompGrBinds { EntityHandle entHandle = EntityHandle_MAX; GrBindsHandle grBindsHandle = GrBindsHandle_MAX; - VkDeviceMemory deviceMemoryVert = VK_NULL_HANDLE; - VkDeviceMemory deviceMemoryInst = VK_NULL_HANDLE; + VkPipelineLayout vkPipelineLayout = VK_NULL_HANDLE; + VkDescriptorSet vkDescriptorSet = VK_NULL_HANDLE; VkBuffer vertexBuffer = VK_NULL_HANDLE; uint32_t vertexFirstBinding = 0; uint32_t vertexCount = 0; @@ -54,8 +54,6 @@ struct CompGrBinds { uint32_t instanceCount = 0; VkDeviceSize instanceOffsets = 0; DynArray<InstPos> instances{0}; - VkPipelineLayout vkPipelineLayout = VK_NULL_HANDLE; - VkDescriptorSet vkDescriptorSet = VK_NULL_HANDLE; }; struct CompInstance { diff --git a/src/entities.cpp b/src/entities.cpp index 75b56f4..b439da1 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -2,11 +2,57 @@ #include "entities.hpp" DynArray<EntityType> globalEntityTypes{16}; +VkDescriptorSetLayout vkDescriptorSetLayout_Texture = VK_NULL_HANDLE; +VkPipelineLayout vkPipelineLayout_Texture = VK_NULL_HANDLE; +VkSampler vkSampler_Texture = VK_NULL_HANDLE; + +VkPipelineLayoutCreateInfo sharedVkPipelineLayoutCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .setLayoutCount = 0, + .pSetLayouts = nullptr, + .pushConstantRangeCount = 0, + .pPushConstantRanges = nullptr, +}; + +VkWriteDescriptorSet uboDescriptor { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = nullptr, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pImageInfo = nullptr, + .pBufferInfo = nullptr, + .pTexelBufferView = nullptr, +}; + +VkDescriptorImageInfo textureDescriptorInfo { + .sampler = nullptr, + .imageView = nullptr, + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, +}; + +VkWriteDescriptorSet samplerDescriptor { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = nullptr, + .dstBinding = 1, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = &textureDescriptorInfo, + .pBufferInfo = nullptr, + .pTexelBufferView = nullptr, +}; void EntityType_Init() { globalEntityTypes.Push( EntityType { - .modelFile = "assets/models/cube.gltf", + .modelsDir = "assets/models", + .modelFile = "cube.gltf", .entityTypeCode = "EntTypeCube", .entityHandle = ECS_CreateEntity(), .startingInstanceCount = 16, @@ -19,6 +65,60 @@ void EntityType_Init() { } ); + VkDescriptorSetLayoutBinding vkDescriptorSetLayoutBindings[2]; + for (long i = 0; i < 2; ++i) { + vkDescriptorSetLayoutBindings[i].pImmutableSamplers = nullptr; + } + vkDescriptorSetLayoutBindings[0].binding = 0; + vkDescriptorSetLayoutBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + vkDescriptorSetLayoutBindings[0].descriptorCount = 1; + vkDescriptorSetLayoutBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + vkDescriptorSetLayoutBindings[1].binding = 1; + vkDescriptorSetLayoutBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + vkDescriptorSetLayoutBindings[1].descriptorCount = 1; + vkDescriptorSetLayoutBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + VkDescriptorSetLayoutCreateInfo vkDescriptorSetLayoutCreateInfo { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .bindingCount = 2, + .pBindings = vkDescriptorSetLayoutBindings, + }; + vkCreateDescriptorSetLayout(vkDevice, &vkDescriptorSetLayoutCreateInfo, vkAllocator, &vkDescriptorSetLayout_Texture); + + VkPipelineLayoutCreateInfo vkPipelineLayoutCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .setLayoutCount = 1, + .pSetLayouts = &vkDescriptorSetLayout_Texture, + .pushConstantRangeCount = 0, + .pPushConstantRanges = nullptr, + }; + vkCreatePipelineLayout(vkDevice, &vkPipelineLayoutCreateInfo, vkAllocator, &vkPipelineLayout_Texture); + + VkSamplerCreateInfo vkSamplerCreateInfo; + vkSamplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + vkSamplerCreateInfo.pNext = nullptr; + vkSamplerCreateInfo.flags = 0; + vkSamplerCreateInfo.magFilter = VK_FILTER_NEAREST; + vkSamplerCreateInfo.minFilter = VK_FILTER_NEAREST; + vkSamplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + vkSamplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + vkSamplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + vkSamplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + vkSamplerCreateInfo.mipLodBias = 0.0f; + vkSamplerCreateInfo.anisotropyEnable = VK_TRUE; + vkSamplerCreateInfo.maxAnisotropy = vkPhysicalDeviceProperties.limits.maxSamplerAnisotropy; + vkSamplerCreateInfo.compareEnable = VK_FALSE; + vkSamplerCreateInfo.compareOp = VK_COMPARE_OP_ALWAYS; + vkSamplerCreateInfo.minLod = 0.0f; + // TODO MipMap + vkSamplerCreateInfo.maxLod = 1; + vkSamplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; + vkSamplerCreateInfo.unnormalizedCoordinates = VK_FALSE; + vkCreateSampler(vkDevice, &vkSamplerCreateInfo, vkAllocator, &vkSampler_Texture); + long entityTypeCount = globalEntityTypes.Count(); for (long i = 0; i < entityTypeCount; ++i) { EntityType_Load(globalEntityTypes[i]); @@ -28,14 +128,27 @@ void EntityType_Init() { void EntityType_Load(EntityType &et) { assert(et.startingInstanceCount > 0); if (et.modelFile != nullptr && et.modelFile != CAFE_BABE(char)) { + // assert(et.vkDescriptorSetLayoutCreateInfo != nullptr && et.vkDescriptorSetLayoutCreateInfo != CAFE_BABE(VkDescriptorSetLayoutCreateInfo) && "EntityType with a defined model must also contain appropriate Vulkan CreateInfos"); // assert(et.vkPipelineLayoutCreateInfo != nullptr && et.vkPipelineLayoutCreateInfo != CAFE_BABE(VkPipelineLayoutCreateInfo) && "EntityType with a defined model must also contain appropriate Vulkan CreateInfos"); - AssetHandle assetHandle{AM_Register(et.modelFile)}; + + char modelPath[128]; + memset(modelPath, '\0', 128); + snprintf(modelPath, 128, "%s/%s", et.modelsDir, et.modelFile); + AssetHandle assetHandle{AM_Register(modelPath)}; const Asset *asset = AM_Get(assetHandle); CompGrBinds &grBinds = ECS_CreateGrBinds(et.entityHandle); - // auto vkResult = vkCreatePipelineLayout(vkDevice, et.vkPipelineLayoutCreateInfo, vkAllocator, &grBinds.vkPipelineLayout); + /* + * 2023-09-13 - JCB + * I don't like that we're just copying this. + * This should be moved to window.cpp. + */ + grBinds.vkPipelineLayout = vkPipelineLayout_Texture; + // et.textureSampler = vkPipelineLayout_Texture; + // VkResult vkResult = vkCreateDescriptorSetLayout(vkDevice, et.vkDescriptorSetLayoutCreateInfo, vkAllocator, &grBinds.vkDescriptorSetLayout); + // assert(vkResult == VK_SUCCESS); + // vkResult = vkCreatePipelineLayout(vkDevice, et.vkPipelineLayoutCreateInfo, vkAllocator, &grBinds.vkPipelineLayout); // assert(vkResult == VK_SUCCESS); - // TODO grBinds.vkDescriptorSet cgltf_options options{}; // TODO allocator @@ -43,10 +156,224 @@ void EntityType_Load(EntityType &et) { cgltf_result result = cgltf_parse(&options, asset->ptr, asset->size, &gltfData); assert(result == cgltf_result_success); // TODO consider using AssetHandler OR loading this directly to the GPU - result = cgltf_load_buffers(&options, gltfData, et.modelFile); + result = cgltf_load_buffers(&options, gltfData, modelPath); assert(result == cgltf_result_success); result = cgltf_validate(gltfData); assert(result == cgltf_result_success); + assert(gltfData->images_count < 2); + + // AssetHandle textureAssetHandle = AssetHandle_MAX; + if (gltfData->images_count == 1) { + char imagePath[128]; + memset(imagePath, '\0', 128); + snprintf(imagePath, 128, "%s/%s", et.modelsDir, gltfData->images[0].uri); + + int pixelWidth, pixelHeight, pixelChannels; + auto *pixels = stbi_load(imagePath, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha); + assert(pixels != nullptr && "sbti_load failed to load image."); + + uint32_t imageSizeBytes = pixelWidth * pixelHeight * pixelChannels; + AssetHandle textureAssetHandle{AM_Register(pixels, imageSizeBytes, imagePath)}; + const Asset *textureAsset = AM_Get(textureAssetHandle); + + 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); + 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, gltfData->buffers[0].data, gltfData->buffers[0].size); + { + 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); + } + + stbi_image_free(pixels); + } + // make sure cgltf can interpret our model for (long i = 0; i < gltfData->accessors_count; ++i) { @@ -120,28 +447,32 @@ void EntityType_Load(EntityType &et) { vkMemoryAllocateInfo.pNext = nullptr; vkMemoryAllocateInfo.allocationSize = vkMemoryRequirements.size; vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &grBinds.deviceMemoryVert); + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &et.deviceMemoryVert); // bind buffers + uint32_t runningOffset = 0; if (et.Importer_GLTF.AccessorIndexVertex > -1) { const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexVertex]; assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); - vkBindBufferMemory(vkDevice, grBinds.vertexBuffer, grBinds.deviceMemoryVert, acc.buffer_view->offset); + vkBindBufferMemory(vkDevice, grBinds.vertexBuffer, et.deviceMemoryVert, runningOffset); + runningOffset += acc.buffer_view->size; } if (et.Importer_GLTF.AccessorIndexNormal > -1) { const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexNormal]; assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); - vkBindBufferMemory(vkDevice, grBinds.normalsBuffer, grBinds.deviceMemoryVert, acc.buffer_view->offset); + vkBindBufferMemory(vkDevice, grBinds.normalsBuffer, et.deviceMemoryVert, runningOffset); + runningOffset += acc.buffer_view->size; } if (et.Importer_GLTF.AccessorIndexUV > -1) { const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexUV]; assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); - vkBindBufferMemory(vkDevice, grBinds.uvBuffer , grBinds.deviceMemoryVert, acc.buffer_view->offset); + vkBindBufferMemory(vkDevice, grBinds.uvBuffer , et.deviceMemoryVert, runningOffset); + runningOffset += acc.buffer_view->size; } if (et.Importer_GLTF.AccessorIndexIndex > -1) { const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexIndex]; assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); - vkBindBufferMemory(vkDevice, grBinds.indexBuffer, grBinds.deviceMemoryVert, acc.buffer_view->offset); + vkBindBufferMemory(vkDevice, grBinds.indexBuffer, et.deviceMemoryVert, runningOffset); } // create transfer items && transfer @@ -161,8 +492,36 @@ void EntityType_Load(EntityType &et) { vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &transferDeviceMemory); vkBindBufferMemory(vkDevice, transferBuffer, transferDeviceMemory, 0); void *data; - vkMapMemory(vkDevice, transferDeviceMemory, 0, gltfData->buffers[0].size, 0, &data); - memcpy(data, gltfData->buffers[0].data, gltfData->buffers[0].size); + vkMapMemory(vkDevice, transferDeviceMemory, 0, vkMemoryRequirements.size, 0, &data); + // memcpy(data, gltfData->buffers[0].data, vkMemoryRequirements.size); + uint32_t runningOffset2 = 0; + if (et.Importer_GLTF.AccessorIndexVertex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexVertex]; + char *dstPtr = static_cast<char *>(data) + runningOffset2; + char *srcPtr = static_cast<char *>(gltfData->buffers[0].data) + acc.buffer_view->offset; + memcpy(dstPtr, srcPtr, acc.buffer_view->size); + runningOffset2 += acc.buffer_view->size; + } + if (et.Importer_GLTF.AccessorIndexNormal > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexNormal]; + char *dstPtr = static_cast<char *>(data) + runningOffset2; + char *srcPtr = static_cast<char *>(gltfData->buffers[0].data) + acc.buffer_view->offset; + memcpy(dstPtr, srcPtr, acc.buffer_view->size); + runningOffset2 += acc.buffer_view->size; + } + if (et.Importer_GLTF.AccessorIndexUV > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexUV]; + char *dstPtr = static_cast<char *>(data) + runningOffset2; + char *srcPtr = static_cast<char *>(gltfData->buffers[0].data) + acc.buffer_view->offset; + memcpy(dstPtr, srcPtr, acc.buffer_view->size); + runningOffset2 += acc.buffer_view->size; + } + if (et.Importer_GLTF.AccessorIndexIndex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexIndex]; + char *dstPtr = static_cast<char *>(data) + runningOffset2; + char *srcPtr = static_cast<char *>(gltfData->buffers[0].data) + acc.buffer_view->offset; + memcpy(dstPtr, srcPtr, acc.buffer_view->size); + } vkUnmapMemory(vkDevice, transferDeviceMemory); VkCommandBufferBeginInfo vkCommandBufferBeginInfo; @@ -207,7 +566,7 @@ void EntityType_Load(EntityType &et) { vkEndCommandBuffer(transferCommandBuffer); - VkSubmitInfo submitInfo{}; + VkSubmitInfo submitInfo; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.pNext = nullptr; submitInfo.waitSemaphoreCount = 0; @@ -232,8 +591,8 @@ void EntityType_Load(EntityType &et) { vkGetBufferMemoryRequirements(vkDevice, grBinds.instanceBuffer, &vkMemoryRequirementsInst); vkMemoryAllocateInfo.allocationSize = vkMemoryRequirementsInst.size; vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemoryRequirementsInst.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &grBinds.deviceMemoryInst); - vkBindBufferMemory(vkDevice, grBinds.instanceBuffer, grBinds.deviceMemoryInst, 0); + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &et.deviceMemoryInst); + vkBindBufferMemory(vkDevice, grBinds.instanceBuffer, et.deviceMemoryInst, 0); // cleanup cgltf_free(gltfData); @@ -244,8 +603,8 @@ void EntityType_Teardown() { long entityTypeCount = globalEntityTypes.Count(); for (long i = 0; i < entityTypeCount; ++i) { if (globalEntityTypes[i].modelFile == nullptr) continue; + auto *et = &globalEntityTypes[i]; auto *grBinds = ECS_GetGrBinds(globalEntityTypes[i].entityHandle); - vkDestroyPipelineLayout(vkDevice, grBinds->vkPipelineLayout, vkAllocator); if (grBinds->vertexBuffer != VK_NULL_HANDLE) vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); if (grBinds->normalsBuffer != VK_NULL_HANDLE) @@ -256,9 +615,22 @@ void EntityType_Teardown() { vkDestroyBuffer(vkDevice, grBinds->indexBuffer, vkAllocator); if (grBinds->instanceBuffer != VK_NULL_HANDLE) vkDestroyBuffer(vkDevice, grBinds->instanceBuffer, vkAllocator); - if (grBinds->deviceMemoryInst != VK_NULL_HANDLE) - vkFreeMemory(vkDevice, grBinds->deviceMemoryInst, vkAllocator); - if (grBinds->deviceMemoryVert != VK_NULL_HANDLE) - vkFreeMemory(vkDevice, grBinds->deviceMemoryVert, vkAllocator); + + 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) + vkFreeMemory(vkDevice, et->deviceMemoryVert, vkAllocator); + if (et->deviceMemoryTexture != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, et->deviceMemoryTexture, vkAllocator); } + if (vkSampler_Texture != VK_NULL_HANDLE) + vkDestroySampler(vkDevice, vkSampler_Texture, vkAllocator); + if (vkPipelineLayout_Texture != VK_NULL_HANDLE) + vkDestroyPipelineLayout(vkDevice, vkPipelineLayout_Texture, vkAllocator); + if (vkDescriptorSetLayout_Texture != VK_NULL_HANDLE) + vkDestroyDescriptorSetLayout(vkDevice, vkDescriptorSetLayout_Texture, vkAllocator); } diff --git a/src/entities.hpp b/src/entities.hpp index 53fe0d9..98aba33 100644 --- a/src/entities.hpp +++ b/src/entities.hpp @@ -2,6 +2,7 @@ #define PKE_ENTITIES_HPP #include "vendor/cgltf-include.hpp" +#include "vendor/stb_image_include.hpp" #include "ecs.hpp" #include "components.hpp" #include "asset-manager.hpp" @@ -11,10 +12,15 @@ #include <vulkan/vulkan_core.h> struct EntityType { + const char *modelsDir = nullptr; const char *modelFile = nullptr; const char *entityTypeCode = nullptr; EntityHandle entityHandle = EntityHandle_MAX; - VkPipelineLayoutCreateInfo *vkPipelineLayoutCreateInfo = nullptr; + VkDeviceMemory deviceMemoryVert = VK_NULL_HANDLE; + VkDeviceMemory deviceMemoryInst = VK_NULL_HANDLE; + VkDeviceMemory deviceMemoryTexture = VK_NULL_HANDLE; + VkImage textureImage = VK_NULL_HANDLE; + VkImageView textureImageView = VK_NULL_HANDLE; uint32_t startingInstanceCount = 1024; struct Importer_GLTF { int16_t AccessorIndexVertex = -1; diff --git a/src/window.cpp b/src/window.cpp index 084f5c2..02249a5 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1020,6 +1020,29 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { throw "failed to begin recording command buffer"; } + // TODO there should be a RenderPass that sandwiches this somewhere + const uint64_t bindBucketCount = ECS_GetGrBinds_BucketCount(); + for (long b = 0; b < bindBucketCount; ++b) { + uint64_t itemCount; + CompGrBinds *items = ECS_GetGrBinds(b, itemCount); + for (long i = 0; i < itemCount; ++i) { + CompGrBinds *binder = &items[i]; + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->vkPipelineLayout, 0U, 1U, &binder->vkDescriptorSet, 0, {}); + vkCmdBindVertexBuffers(commandBuffer, binder->vertexFirstBinding, binder->vertexCount, &binder->vertexBuffer, &binder->vertexOffsets); + if (binder->normalsCount > 0) + vkCmdBindVertexBuffers(commandBuffer, binder->normalsFirstBinding, binder->normalsCount, &binder->normalsBuffer, &binder->normalsOffsets); + if (binder->uvCount > 0) + vkCmdBindVertexBuffers(commandBuffer, binder->uvFirstBinding, binder->uvCount, &binder->uvBuffer, &binder->uvOffsets); + if (binder->indexCount > 0) + vkCmdBindIndexBuffer(commandBuffer, binder->indexBuffer, binder->vertexOffsets, VK_INDEX_TYPE_UINT16); + + vkCmdBindVertexBuffers(commandBuffer, binder->indexFirstBinding, binder->instanceCount, &binder->instanceBuffer, &binder->instanceOffsets); + + vkCmdDrawIndexed(commandBuffer, binder->indexCount, binder->instanceCount, 0, 0, 0); + } + } + + // present pass VkClearValue clearColor = {{{0.0f, 0.0f, 0.0f, 1.0f}}}; VkRenderPassBeginInfo renderPassInfo{}; @@ -1049,28 +1072,6 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { vkCmdSetViewport(commandBuffer, 0, 1, &viewport); vkCmdSetScissor(commandBuffer, 0, 1, &scissor); - - const uint64_t bindBucketCount = ECS_GetGrBinds_BucketCount(); - for (long b = 0; b < bindBucketCount; ++b) { - uint64_t itemCount; - CompGrBinds *items = ECS_GetGrBinds(b, itemCount); - for (long i = 0; i < itemCount; ++i) { - CompGrBinds *binder = &items[i]; - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->vkPipelineLayout, 0U, 1U, &binder->vkDescriptorSet, 0, {}); - vkCmdBindVertexBuffers(commandBuffer, binder->vertexFirstBinding, binder->vertexCount, &binder->vertexBuffer, &binder->vertexOffsets); - if (binder->normalsCount > 0) - vkCmdBindVertexBuffers(commandBuffer, binder->normalsFirstBinding, binder->normalsCount, &binder->normalsBuffer, &binder->normalsOffsets); - if (binder->uvCount > 0) - vkCmdBindVertexBuffers(commandBuffer, binder->uvFirstBinding, binder->uvCount, &binder->uvBuffer, &binder->uvOffsets); - if (binder->indexCount > 0) - vkCmdBindIndexBuffer(commandBuffer, binder->indexBuffer, binder->vertexOffsets, VK_INDEX_TYPE_UINT16); - - vkCmdBindVertexBuffers(commandBuffer, binder->indexFirstBinding, binder->instanceCount, &binder->instanceBuffer, &binder->instanceOffsets); - - vkCmdDrawIndexed(commandBuffer, binder->indexCount, binder->instanceCount, 0, 0, 0); - } - } - // reminder that present.vert is a triangle vkCmdDraw(commandBuffer, 3, 1, 0, 0); |
