diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-05-20 21:08:19 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-05-20 21:08:19 -0400 |
| commit | 40d69e7e40a18865a31af2f55efcde369d36dbbb (patch) | |
| tree | 95a2cbbe40192183d13f846f3444b32d7e12b0e8 /src/font.cpp | |
| parent | ead9e484db969a880470d625b1884aced296e722 (diff) | |
pke: serialization overhaul + embedded assets
Diffstat (limited to 'src/font.cpp')
| -rw-r--r-- | src/font.cpp | 530 |
1 files changed, 285 insertions, 245 deletions
diff --git a/src/font.cpp b/src/font.cpp index c94890b..380827b 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -8,6 +8,7 @@ #include "vendor-stb-image-include.h" #include "game-settings.hpp" #include "ecs.hpp" +#include "../embed/embedded-fonts.h" #include <vulkan/vulkan_core.h> @@ -253,6 +254,21 @@ void FontType_Init() { ft->glyphs = nullptr; ft->renders = nullptr; } + AssetKey ak_img = "fnt_mquin_img\0\0"; + AssetKey ak_glyphs = "fnt_mquin_gly\0\0"; + AssetHandle ah_img = AM_Register_Static(ak_img, PKE_ASSET_TYPE_TEXTURE, embedded_fonts[0].data, embedded_fonts[0].size); + AssetHandle ah_glyphs = AM_Register_Static(ak_glyphs, PKE_ASSET_TYPE_UNSET, embedded_fonts[1].data, embedded_fonts[1].size); + FontTypeMSDFSettings msdf_s; + msdf_s.minimum_scale = 144; + msdf_s.px_range = 4; + FontTypeSpacing spacing; + spacing.geometry_scale = 0.0625; + spacing.em_size = 1; + spacing.ascender_y = 0.875; + spacing.descender_y = -0.125; + spacing.line_height = 1.125; + spacing.underline_y = 0.0625; + FontType_RegisterFont(cstring_to_pk_cstr("fnt_mquin_7y"), ah_img, ah_glyphs, &msdf_s, &spacing); } void FontType_Teardown() { @@ -471,6 +487,11 @@ void FontType_Deserialize(std::istream &stream) { } } +FontType* FontType_Get(FontTypeIndex idx) { + assert(idx < ftd.h_ft); + return &ftd.arr_ft[static_cast<FontTypeIndex_T>(idx)]; +} + FontType* FontType_GetFonts(FontTypeIndex &count) { count = ftd.h_ft; return ftd.arr_ft; @@ -524,116 +545,124 @@ FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle ft->atlas_size.x = (float)txtr_x; ft->atlas_size.y = (float)txtr_y; - // buffers + ECS_CreateEntity(ft); - glm::vec2 atlas_size_buffer[4]; - for (int i = 0; i < 4; ++i) { - atlas_size_buffer[i] = ft->atlas_size; - } + if (window != NULL) { - pkvk_buffer_create_data create_data{}; - create_data.buffer_byte_length[0] = sizeof(pkeIntrinsicsPlane.vert[0]) * 4; - create_data.buffer_byte_length[1] = sizeof(pkeIntrinsicsPlane.uv[0]) * 4; - create_data.buffer_byte_length[2] = sizeof(atlas_size_buffer[0]) * 4; - create_data.buffer_byte_length[3] = sizeof(pkeIntrinsicsPlane.index[0]) * 6; - create_data.buffer_byte_length[4] = sizeof(FontInstanceBufferItem); - create_data.src_data[0] = &pkeIntrinsicsPlane.vert; - create_data.src_data[1] = &pkeIntrinsicsPlane.uv; - create_data.src_data[2] = &atlas_size_buffer; - create_data.src_data[3] = &pkeIntrinsicsPlane.index; - create_data.src_data[4] = nullptr; - create_data.n_buffers = 5; - create_data.index_index = 3; - create_data.index_instance = 4; - - pkvk_buffer_create_data_out out{}; - pkvk_buffer_create(&create_data, &out); - - ft->bindings.bd_vertex.buffer = out.buffers[0]; - ft->bindings.bd_vertex.firstBinding = 0; - ft->bindings.bd_vertex.bindingCount = 1; - ft->bindings.bd_uv.buffer = out.buffers[1]; - ft->bindings.bd_uv.firstBinding = 1; - ft->bindings.bd_uv.bindingCount = 1; - ft->bindings.bd_atlas_size.buffer = out.buffers[2]; - ft->bindings.bd_atlas_size.firstBinding = 2; - ft->bindings.bd_atlas_size.bindingCount = 1; - ft->bindings.bd_index.buffer = out.buffers[3]; - ft->bindings.bd_index.firstBinding = 0; - ft->bindings.bd_index.bindingCount = 1; - ft->bindings.index_count = 6; - ft->bindings.bd_instance.buffer = out.buffers[4]; - ft->bindings.bd_instance.firstBinding = 3; - ft->bindings.bd_instance.bindingCount = 1; - ft->gr.deviceMemoryVert = out.device_memory_vertex; - ft->gr.deviceMemoryInst = out.device_memory_instance; - - ft->bindings.instance_buffer_max_count = out.memory_requirements_instance.size / sizeof(FontInstanceBufferItem); - - // texture - - pkvk_texture_upload_data txtr_data{}; - txtr_data.bytes = txtr_bytes; - txtr_data.n_bytes = imageSizeBytes; - txtr_data.width = (uint32_t)txtr_x; - txtr_data.height = (uint32_t)txtr_y; - - pkvk_texture_upload_data_out txtr_out{}; - pkvk_texture_upload(&txtr_data, &txtr_out); - - ft->gr.textureImage = txtr_out.image; - ft->gr.textureImageView = txtr_out.image_view; - ft->gr.deviceMemoryTexture = txtr_out.device_memory; - - free(txtr_bytes); - - /* - * Vulkan descriptor sets - */ - VkDescriptorPoolSize descriptorPoolSizes[1]; - descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptorPoolSizes[0].descriptorCount = (uint32_t)1; - - VkDescriptorPoolCreateInfo vkDescriptorPoolCreateInfo; - vkDescriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - vkDescriptorPoolCreateInfo.pNext = nullptr; - vkDescriptorPoolCreateInfo.flags = 0; - vkDescriptorPoolCreateInfo.maxSets = (uint32_t)1; - vkDescriptorPoolCreateInfo.poolSizeCount = (uint32_t)1; - vkDescriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes; - - // consider making me a global pool - vkResult = vkCreateDescriptorPool(vkDevice, &vkDescriptorPoolCreateInfo, vkAllocator, &ft->gr.vkDescriptorPool); - assert(vkResult == VK_SUCCESS); - - VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo; - vkDescriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - vkDescriptorSetAllocateInfo.pNext = nullptr; - vkDescriptorSetAllocateInfo.descriptorPool = ft->gr.vkDescriptorPool; - vkDescriptorSetAllocateInfo.descriptorSetCount = (uint32_t)1; - vkDescriptorSetAllocateInfo.pSetLayouts = &pkePipelines.descr_layouts.named.txtr; - - vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, &ft->gr.vkDescriptorSet); - assert(vkResult == VK_SUCCESS); - - VkDescriptorImageInfo textureDescriptorInfo; - textureDescriptorInfo.sampler = global_sampler; - textureDescriptorInfo.imageView = ft->gr.textureImageView; - textureDescriptorInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkWriteDescriptorSet writeDescriptorSet; - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.pNext = nullptr; - writeDescriptorSet.dstSet = ft->gr.vkDescriptorSet; - writeDescriptorSet.dstBinding = (uint32_t)0; - writeDescriptorSet.dstArrayElement = (uint32_t)0; - writeDescriptorSet.descriptorCount = (uint32_t)1; - writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - writeDescriptorSet.pImageInfo = &textureDescriptorInfo; - writeDescriptorSet.pBufferInfo = nullptr; - writeDescriptorSet.pTexelBufferView = nullptr; - - vkUpdateDescriptorSets(vkDevice, (uint32_t)1, &writeDescriptorSet, 0, nullptr); + // buffers + + glm::vec2 atlas_size_buffer[4]; + for (int i = 0; i < 4; ++i) { + atlas_size_buffer[i] = ft->atlas_size; + } + + pkvk_buffer_create_data create_data{}; + create_data.buffer_byte_length[0] = sizeof(pkeIntrinsicsPlane.vert[0]) * 4; + create_data.buffer_byte_length[1] = sizeof(pkeIntrinsicsPlane.uv[0]) * 4; + create_data.buffer_byte_length[2] = sizeof(atlas_size_buffer[0]) * 4; + create_data.buffer_byte_length[3] = sizeof(pkeIntrinsicsPlane.index[0]) * 6; + create_data.buffer_byte_length[4] = sizeof(FontInstanceBufferItem); + create_data.src_data[0] = &pkeIntrinsicsPlane.vert; + create_data.src_data[1] = &pkeIntrinsicsPlane.uv; + create_data.src_data[2] = &atlas_size_buffer; + create_data.src_data[3] = &pkeIntrinsicsPlane.index; + create_data.src_data[4] = nullptr; + create_data.n_buffers = 5; + create_data.index_index = 3; + create_data.index_instance = 4; + + pkvk_buffer_create_data_out out{}; + pkvk_buffer_create(&create_data, &out); + + ft->bindings.bd_vertex.buffer = out.buffers[0]; + ft->bindings.bd_vertex.firstBinding = 0; + ft->bindings.bd_vertex.bindingCount = 1; + ft->bindings.bd_uv.buffer = out.buffers[1]; + ft->bindings.bd_uv.firstBinding = 1; + ft->bindings.bd_uv.bindingCount = 1; + ft->bindings.bd_atlas_size.buffer = out.buffers[2]; + ft->bindings.bd_atlas_size.firstBinding = 2; + ft->bindings.bd_atlas_size.bindingCount = 1; + ft->bindings.bd_index.buffer = out.buffers[3]; + ft->bindings.bd_index.firstBinding = 0; + ft->bindings.bd_index.bindingCount = 1; + ft->bindings.index_count = 6; + ft->bindings.bd_instance.buffer = out.buffers[4]; + ft->bindings.bd_instance.firstBinding = 3; + ft->bindings.bd_instance.bindingCount = 1; + ft->gr.deviceMemoryVert = out.device_memory_vertex; + ft->gr.deviceMemoryInst = out.device_memory_instance; + + ft->bindings.instance_buffer_max_count = out.memory_requirements_instance.size / sizeof(FontInstanceBufferItem); + + // texture + + pkvk_texture_upload_data txtr_data{}; + txtr_data.bytes = txtr_bytes; + txtr_data.n_bytes = imageSizeBytes; + txtr_data.width = (uint32_t)txtr_x; + txtr_data.height = (uint32_t)txtr_y; + + pkvk_texture_upload_data_out txtr_out{}; + pkvk_texture_upload(&txtr_data, &txtr_out); + + ft->gr.textureImage = txtr_out.image; + ft->gr.textureImageView = txtr_out.image_view; + ft->gr.deviceMemoryTexture = txtr_out.device_memory; + + free(txtr_bytes); + + /* + * Vulkan descriptor sets + */ + VkDescriptorPoolSize descriptorPoolSizes[1]; + descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptorPoolSizes[0].descriptorCount = (uint32_t)1; + + VkDescriptorPoolCreateInfo vkDescriptorPoolCreateInfo; + vkDescriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + vkDescriptorPoolCreateInfo.pNext = nullptr; + vkDescriptorPoolCreateInfo.flags = 0; + vkDescriptorPoolCreateInfo.maxSets = (uint32_t)1; + vkDescriptorPoolCreateInfo.poolSizeCount = (uint32_t)1; + vkDescriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes; + + // consider making me a global pool + vkResult = vkCreateDescriptorPool(vkDevice, &vkDescriptorPoolCreateInfo, vkAllocator, &ft->gr.vkDescriptorPool); + assert(vkResult == VK_SUCCESS); + + VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo; + vkDescriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + vkDescriptorSetAllocateInfo.pNext = nullptr; + vkDescriptorSetAllocateInfo.descriptorPool = ft->gr.vkDescriptorPool; + vkDescriptorSetAllocateInfo.descriptorSetCount = (uint32_t)1; + vkDescriptorSetAllocateInfo.pSetLayouts = &pkePipelines.descr_layouts.named.txtr; + + vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, &ft->gr.vkDescriptorSet); + assert(vkResult == VK_SUCCESS); + + VkDescriptorImageInfo textureDescriptorInfo; + textureDescriptorInfo.sampler = global_sampler; + textureDescriptorInfo.imageView = ft->gr.textureImageView; + textureDescriptorInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkWriteDescriptorSet writeDescriptorSet; + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.pNext = nullptr; + writeDescriptorSet.dstSet = ft->gr.vkDescriptorSet; + writeDescriptorSet.dstBinding = (uint32_t)0; + writeDescriptorSet.dstArrayElement = (uint32_t)0; + writeDescriptorSet.descriptorCount = (uint32_t)1; + writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writeDescriptorSet.pImageInfo = &textureDescriptorInfo; + writeDescriptorSet.pBufferInfo = nullptr; + writeDescriptorSet.pTexelBufferView = nullptr; + + vkUpdateDescriptorSets(vkDevice, (uint32_t)1, &writeDescriptorSet, 0, nullptr); + + } else { + free(txtr_bytes); + } AM_Release(fontTextureHandle); AM_Release(glyphsHandle); @@ -727,6 +756,7 @@ void FontType_Unload(FontTypeIndex idx) { ft->title.val = nullptr; ft->title.length = 0; } + ECS_MarkForRemoval(ft); } // TODO perf? @@ -735,7 +765,7 @@ void FontType_Unload(FontTypeIndex idx) { // However, the new buffer is exactly the length it needs to be and no greater. // Consider using a heuristic to allocate a buffer larger than needed. // At the time of writing, the only way to do this is to un-register text. -FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent) { +FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent, pk_uuid uuid) { assert(settings != nullptr); PKVK_TmpBufferDetails tmpBufferDetails{}; VkDeviceSize byteCount; @@ -757,103 +787,157 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr && } fr = &ft->renders[(FontRenderIndex_T)idx_fr]; *fr = {}; + fr->uuid = uuid; ECS_CreateEntity(fr, parent); fr->fr_handle.index_ft = idx_ft; fr->fr_handle.index_fr = idx_fr; fr->settings = *settings; fr->text = str; - // insert new characters into tmp buffer - { - DynArray<uint32_t> glyph_indices; - glyph_indices.Reserve(str.length); - count = 0; - for (i = 0; i < str.length;) { - fgc = nullptr; - u = 0; - // determine unicode char - ii = utf8_to_unicode(&str.val[i], u); - if (ii == 0) { - fprintf(stderr, "failed to determine unicode for character: at byte index: '%i'\n", i); - i += 1; - continue; + if (window != NULL) { + // insert new characters into tmp buffer + { + DynArray<uint32_t> glyph_indices; + glyph_indices.Reserve(str.length); + count = 0; + for (i = 0; i < str.length;) { + fgc = nullptr; + u = 0; + // determine unicode char + ii = utf8_to_unicode(&str.val[i], u); + if (ii == 0) { + fprintf(stderr, "failed to determine unicode for character: at byte index: '%i'\n", i); + i += 1; + continue; + } + i += ii; + + // binary search for glyph details + l = 0; + r = ft->n_glyphs - 1; + do { + m = l + (r-l)/2; + fgc = &ft->glyphs[m]; + if (fgc->unicode < u) + l = m + 1; + else + r = m - 1; + } while (fgc->unicode != u && l <= r); + + if (fgc->unicode != u) { + fprintf(stderr, "font: '%s' does not contain unicode character '%u'\n", ft->title.val, u); + continue; + } + count += 1; + glyph_indices.Push(m); } - i += ii; - - // binary search for glyph details - l = 0; - r = ft->n_glyphs - 1; - do { - m = l + (r-l)/2; - fgc = &ft->glyphs[m]; - if (fgc->unicode < u) - l = m + 1; - else - r = m - 1; - } while (fgc->unicode != u && l <= r); - - if (fgc->unicode != u) { - fprintf(stderr, "font: '%s' does not contain unicode character '%u'\n", ft->title.val, u); - continue; + + // TODO specific bucket + fr->n_glyphs = count; + fr->glyph_indices = pk_new<uint32_t>(count); + for (i = 0; i < count; ++i) { + fr->glyph_indices[i] = glyph_indices[i]; } - count += 1; - glyph_indices.Push(m); } - // TODO specific bucket - fr->n_glyphs = count; - fr->glyph_indices = pk_new<uint32_t>(count); - for (i = 0; i < count; ++i) { - fr->glyph_indices[i] = glyph_indices[i]; - } - } + VkDeviceSize item_count_orig = ft->bindings.instance_counter; + VkDeviceSize item_length_new = PK_MAX(ft->bindings.instance_buffer_max_count, ft->bindings.instance_counter + count); + + // copy existing buffer to new buffer + // create new buffer + if (ft->bindings.instance_buffer_max_count < item_length_new) { + byteCount = sizeof(FontInstanceBufferItem) * item_length_new; + VkBuffer newBuffer; + 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; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + bufferCI.size = byteCount; + vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer); + assert(vkResult == VK_SUCCESS); - VkDeviceSize item_count_orig = ft->bindings.instance_counter; - VkDeviceSize item_length_new = PK_MAX(ft->bindings.instance_buffer_max_count, ft->bindings.instance_counter + count); - - // copy existing buffer to new buffer - // create new buffer - if (ft->bindings.instance_buffer_max_count < item_length_new) { - byteCount = sizeof(FontInstanceBufferItem) * item_length_new; - VkBuffer newBuffer; - 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; - bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - bufferCI.size = byteCount; - vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer); - assert(vkResult == VK_SUCCESS); + VkMemoryRequirements vkMemReqs; + vkGetBufferMemoryRequirements(vkDevice, newBuffer, &vkMemReqs); + assert(sizeof(FontInstanceBufferItem) % vkMemReqs.alignment == 0); - VkMemoryRequirements vkMemReqs; - vkGetBufferMemoryRequirements(vkDevice, newBuffer, &vkMemReqs); - assert(sizeof(FontInstanceBufferItem) % vkMemReqs.alignment == 0); + vkDestroyBuffer(vkDevice, newBuffer, vkAllocator); + newBuffer = VK_NULL_HANDLE; - vkDestroyBuffer(vkDevice, newBuffer, vkAllocator); - newBuffer = VK_NULL_HANDLE; + bufferCI.size = vkMemReqs.size + (vkMemReqs.alignment - (vkMemReqs.size & vkMemReqs.alignment)); + vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer); + assert(vkResult == VK_SUCCESS); - bufferCI.size = vkMemReqs.size + (vkMemReqs.alignment - (vkMemReqs.size & vkMemReqs.alignment)); - vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer); - assert(vkResult == VK_SUCCESS); + VkDeviceMemory new_memory; + VkMemoryAllocateInfo vkMemoryAllocateInfo; + vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + vkMemoryAllocateInfo.pNext = nullptr; + vkMemoryAllocateInfo.allocationSize = bufferCI.size; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VkDeviceMemory new_memory; - VkMemoryAllocateInfo vkMemoryAllocateInfo; - vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - vkMemoryAllocateInfo.pNext = nullptr; - vkMemoryAllocateInfo.allocationSize = bufferCI.size; - vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + vkResult = vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &new_memory); + assert(vkResult == VK_SUCCESS); - vkResult = vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &new_memory); - assert(vkResult == VK_SUCCESS); + vkResult = vkBindBufferMemory(vkDevice, newBuffer, new_memory, 0); + assert(vkResult == VK_SUCCESS); - vkResult = vkBindBufferMemory(vkDevice, newBuffer, new_memory, 0); - assert(vkResult == VK_SUCCESS); + if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE && ft->bindings.instance_counter > 0) { + PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails, PKVK_TmpBufferFlags_NONE); + + VkCommandBufferBeginInfo vkCommandBufferBeginInfo; + vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + vkCommandBufferBeginInfo.pNext = nullptr; + // TODO consider single-use? + vkCommandBufferBeginInfo.flags = 0; + vkCommandBufferBeginInfo.pInheritanceInfo = nullptr; + vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo); + assert(vkResult == VK_SUCCESS); + + VkBufferCopy vk_buffer_copy{}; + vk_buffer_copy.srcOffset = 0; + vk_buffer_copy.dstOffset = 0; + vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * ft->bindings.instance_counter; + assert(vk_buffer_copy.size != 0); + vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, ft->bindings.bd_instance.buffer, newBuffer, 1, &vk_buffer_copy); + + vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer); + assert(vkResult == VK_SUCCESS); + + 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 = &tmpBufferDetails.cmdBuffer; + submitInfo.signalSemaphoreCount = 0; + submitInfo.pSignalSemaphores = nullptr; + vkResult = vkQueueSubmit(tmpBufferDetails.queue, 1, &submitInfo, nullptr); + assert(vkResult == VK_SUCCESS); + vkResult = vkQueueWaitIdle(tmpBufferDetails.queue); + assert(vkResult == VK_SUCCESS); + + PKVK_EndBuffer(tmpBufferDetails, PKVK_TmpBufferFlags_NONE); + } + if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, ft->bindings.bd_instance.buffer, vkAllocator); + if (ft->gr.deviceMemoryInst != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, ft->gr.deviceMemoryInst, vkAllocator); - if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE && ft->bindings.instance_counter > 0) { - PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails, PKVK_TmpBufferFlags_NONE); + ft->gr.deviceMemoryInst = new_memory; + ft->bindings.bd_instance.buffer = newBuffer; + } + ft->bindings.instance_buffer_max_count = item_length_new; + ft->bindings.instance_counter += count; + + // create tmp local buffer & copy data to graphics card + byteCount = sizeof(FontInstanceBufferItem) * count; + PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails); + { VkCommandBufferBeginInfo vkCommandBufferBeginInfo; vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -864,12 +948,13 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr && vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo); assert(vkResult == VK_SUCCESS); + FontType_Inner_CalcTransforms(ft, fr, (FontInstanceBufferItem*)tmpBufferDetails.deviceData); + VkBufferCopy vk_buffer_copy{}; vk_buffer_copy.srcOffset = 0; - vk_buffer_copy.dstOffset = 0; - vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * ft->bindings.instance_counter; - assert(vk_buffer_copy.size != 0); - vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, ft->bindings.bd_instance.buffer, newBuffer, 1, &vk_buffer_copy); + vk_buffer_copy.dstOffset = sizeof(FontInstanceBufferItem) * item_count_orig; + vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * count; + vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, ft->bindings.bd_instance.buffer, 1, &vk_buffer_copy); vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer); assert(vkResult == VK_SUCCESS); @@ -888,65 +973,20 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr && assert(vkResult == VK_SUCCESS); vkResult = vkQueueWaitIdle(tmpBufferDetails.queue); assert(vkResult == VK_SUCCESS); - - PKVK_EndBuffer(tmpBufferDetails, PKVK_TmpBufferFlags_NONE); } - if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, ft->bindings.bd_instance.buffer, vkAllocator); - if (ft->gr.deviceMemoryInst != VK_NULL_HANDLE) - vkFreeMemory(vkDevice, ft->gr.deviceMemoryInst, vkAllocator); - - ft->gr.deviceMemoryInst = new_memory; - ft->bindings.bd_instance.buffer = newBuffer; - } - ft->bindings.instance_buffer_max_count = item_length_new; - ft->bindings.instance_counter += count; - - // create tmp local buffer & copy data to graphics card - byteCount = sizeof(FontInstanceBufferItem) * count; - PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails); - { - - VkCommandBufferBeginInfo vkCommandBufferBeginInfo; - vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - vkCommandBufferBeginInfo.pNext = nullptr; - // TODO consider single-use? - vkCommandBufferBeginInfo.flags = 0; - vkCommandBufferBeginInfo.pInheritanceInfo = nullptr; - vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo); - assert(vkResult == VK_SUCCESS); - - FontType_Inner_CalcTransforms(ft, fr, (FontInstanceBufferItem*)tmpBufferDetails.deviceData); - - VkBufferCopy vk_buffer_copy{}; - vk_buffer_copy.srcOffset = 0; - vk_buffer_copy.dstOffset = sizeof(FontInstanceBufferItem) * item_count_orig; - vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * count; - vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, ft->bindings.bd_instance.buffer, 1, &vk_buffer_copy); - - vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer); - assert(vkResult == VK_SUCCESS); - - 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 = &tmpBufferDetails.cmdBuffer; - submitInfo.signalSemaphoreCount = 0; - submitInfo.pSignalSemaphores = nullptr; - vkResult = vkQueueSubmit(tmpBufferDetails.queue, 1, &submitInfo, nullptr); - assert(vkResult == VK_SUCCESS); - vkResult = vkQueueWaitIdle(tmpBufferDetails.queue); - assert(vkResult == VK_SUCCESS); + PKVK_EndBuffer(tmpBufferDetails); } - PKVK_EndBuffer(tmpBufferDetails); return fr->fr_handle; } +FontRender *FontType_GetFontRender(FontRenderHandle frh) { + assert(frh.index_ft < ftd.h_ft); + FontType *ft = &ftd.arr_ft[static_cast<FontTypeIndex_T>(frh.index_ft)]; + assert(frh.index_fr < ft->h_render); + return &ft->renders[static_cast<FontRenderIndex_T>(frh.index_fr)]; +} + void FontType_UpdateStringRender(FontRenderHandle frh, FontRenderSettings *settings) { assert(settings != nullptr); assert((FontTypeIndex_T)ftd.h_ft > (FontTypeIndex_T)frh.index_ft); |
