| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -53,14 +53,33 @@ VkShaderModule load_shader_file(const char* path, VkDevice device) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					VkResult create_ui_pipeline(
 | 
					 | 
					 | 
					 | 
					VkResult create_ui_pipeline(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    VkDevice device,
 | 
					 | 
					 | 
					 | 
					    VkDevice device,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    VkRenderPass render_pass,
 | 
					 | 
					 | 
					 | 
					    VkRenderPass render_pass,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    VkDescriptorSetLayout font_samplers_layout,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    VkDescriptorSetLayout font_textures_layout,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    VkPipelineShaderStageCreateInfo* shader_stages,
 | 
					 | 
					 | 
					 | 
					    VkPipelineShaderStageCreateInfo* shader_stages,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    uint32_t shader_stage_count,
 | 
					 | 
					 | 
					 | 
					    uint32_t shader_stage_count,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    VkPipelineVertexInputStateCreateInfo input_info,
 | 
					 | 
					 | 
					 | 
					    VkPipelineVertexInputStateCreateInfo input_info,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    VkPipelineLayoutCreateInfo layout_info,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    VkPipelineInputAssemblyStateCreateInfo input_assembly_info,
 | 
					 | 
					 | 
					 | 
					    VkPipelineInputAssemblyStateCreateInfo input_assembly_info,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    GraphicsPipeline* pipeline) {
 | 
					 | 
					 | 
					 | 
					    GraphicsPipeline* pipeline) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkResult result;
 | 
					 | 
					 | 
					 | 
					  VkResult result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  VkPushConstantRange push_constants[] = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      .stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      .size = 16,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      .offset = 0,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    },
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  VkDescriptorSetLayout set_layouts[] = {font_samplers_layout, font_textures_layout};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  VkPipelineLayoutCreateInfo layout_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pushConstantRangeCount = sizeof(push_constants)/sizeof(VkPushConstantRange),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pPushConstantRanges = push_constants,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .setLayoutCount = sizeof(set_layouts)/sizeof(VkDescriptorSetLayout),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pSetLayouts = set_layouts,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vkCreatePipelineLayout(device, &layout_info, 0, &pipeline->layout);
 | 
					 | 
					 | 
					 | 
					  result = vkCreatePipelineLayout(device, &layout_info, 0, &pipeline->layout);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -176,12 +195,12 @@ VkResult create_ui_pipeline(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					VkResult create_ui_colored_rect_pipeline(VkDevice device, VkRenderPass render_pass, VkDescriptorSetLayout ui_descriptor_layout, GraphicsPipeline* pipeline) {
 | 
					 | 
					 | 
					 | 
					VkResult create_ui_rect_pipeline(VkDevice device, VkRenderPass render_pass, VkDescriptorSetLayout font_samplers_layout, VkDescriptorSetLayout font_textures_layout, GraphicsPipeline* pipeline) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkShaderModule vert_shader = load_shader_file("shader_src/ui_colored_rect.vert.spv", device);
 | 
					 | 
					 | 
					 | 
					  VkShaderModule vert_shader = load_shader_file("shader_src/ui_rect.vert.spv", device);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(vert_shader == VK_NULL_HANDLE) {
 | 
					 | 
					 | 
					 | 
					  if(vert_shader == VK_NULL_HANDLE) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return VK_ERROR_UNKNOWN;
 | 
					 | 
					 | 
					 | 
					    return VK_ERROR_UNKNOWN;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkShaderModule frag_shader = load_shader_file("shader_src/ui_colored_rect.frag.spv", device);
 | 
					 | 
					 | 
					 | 
					  VkShaderModule frag_shader = load_shader_file("shader_src/ui_rect.frag.spv", device);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(frag_shader == VK_NULL_HANDLE) {
 | 
					 | 
					 | 
					 | 
					  if(frag_shader == VK_NULL_HANDLE) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return VK_ERROR_UNKNOWN;
 | 
					 | 
					 | 
					 | 
					    return VK_ERROR_UNKNOWN;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -210,26 +229,13 @@ VkResult create_ui_colored_rect_pipeline(VkDevice device, VkRenderPass render_pa
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .vertexAttributeDescriptionCount = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
 | 
					 | 
					 | 
					 | 
					    .vertexAttributeDescriptionCount = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkPushConstantRange push_constant = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = 8,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkPipelineLayoutCreateInfo layout_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .setLayoutCount = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pSetLayouts = &ui_descriptor_layout,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pPushConstantRanges = &push_constant,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pushConstantRangeCount = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {
 | 
					 | 
					 | 
					 | 
					  VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
 | 
					 | 
					 | 
					 | 
					    .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .primitiveRestartEnable = VK_FALSE,
 | 
					 | 
					 | 
					 | 
					    .primitiveRestartEnable = VK_FALSE,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkResult result = create_ui_pipeline(device, render_pass, shader_stages, sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), input_info, layout_info, input_assembly_info, pipeline);
 | 
					 | 
					 | 
					 | 
					  VkResult result = create_ui_pipeline(device, render_pass, font_samplers_layout, font_textures_layout, shader_stages, sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), input_info, input_assembly_info, pipeline);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -237,7 +243,7 @@ VkResult create_ui_colored_rect_pipeline(VkDevice device, VkRenderPass render_pa
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDescriptorSetLayout ui_descriptor_layout, VkDescriptorSetLayout font_layout, GraphicsPipeline* pipeline, ComputePipeline* compute) {
 | 
					 | 
					 | 
					 | 
					VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDescriptorSetLayout font_samplers_layout, VkDescriptorSetLayout font_textures_layout, GraphicsPipeline* pipeline, ComputePipeline* compute) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkResult result;
 | 
					 | 
					 | 
					 | 
					  VkResult result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkShaderModule compute_shader = load_shader_file("shader_src/ui_text.comp.spv", device);
 | 
					 | 
					 | 
					 | 
					  VkShaderModule compute_shader = load_shader_file("shader_src/ui_text.comp.spv", device);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(compute_shader == VK_NULL_HANDLE) {
 | 
					 | 
					 | 
					 | 
					  if(compute_shader == VK_NULL_HANDLE) {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -252,18 +258,14 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkPushConstantRange push_constant = {
 | 
					 | 
					 | 
					 | 
					  VkPushConstantRange push_constant = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT,
 | 
					 | 
					 | 
					 | 
					    .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = 8,
 | 
					 | 
					 | 
					 | 
					    .size = 16,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorSetLayout compute_descriptors[] = {font_layout};
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkPipelineLayoutCreateInfo compute_layout_info = {
 | 
					 | 
					 | 
					 | 
					  VkPipelineLayoutCreateInfo compute_layout_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pushConstantRangeCount = 1,
 | 
					 | 
					 | 
					 | 
					    .pushConstantRangeCount = 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pPushConstantRanges = &push_constant,
 | 
					 | 
					 | 
					 | 
					    .pPushConstantRanges = &push_constant,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .setLayoutCount = sizeof(compute_descriptors)/sizeof(VkDescriptorSetLayout),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pSetLayouts = compute_descriptors,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vkCreatePipelineLayout(device, &compute_layout_info, NULL, &compute->layout);
 | 
					 | 
					 | 
					 | 
					  result = vkCreatePipelineLayout(device, &compute_layout_info, NULL, &compute->layout);
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -320,23 +322,13 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .vertexAttributeDescriptionCount = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
 | 
					 | 
					 | 
					 | 
					    .vertexAttributeDescriptionCount = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 
 | 
					 | 
					 | 
					 | 
					 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorSetLayout all_layouts[] = {ui_descriptor_layout, font_layout};
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkPipelineLayoutCreateInfo layout_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .setLayoutCount = sizeof(all_layouts)/sizeof(VkDescriptorSetLayout),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pSetLayouts = all_layouts,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pPushConstantRanges = &push_constant,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pushConstantRangeCount = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {
 | 
					 | 
					 | 
					 | 
					  VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
 | 
					 | 
					 | 
					 | 
					    .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .primitiveRestartEnable = VK_FALSE,
 | 
					 | 
					 | 
					 | 
					    .primitiveRestartEnable = VK_FALSE,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = create_ui_pipeline(device, render_pass, shader_stages, sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), input_info, layout_info, input_assembly_info, pipeline);
 | 
					 | 
					 | 
					 | 
					  result = create_ui_pipeline(device, render_pass, font_samplers_layout, font_textures_layout, shader_stages, sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), input_info, input_assembly_info, pipeline);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -344,219 +336,36 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					VkResult create_font_descriptor_pools(VkDevice device, uint32_t max_sets, VkDescriptorPool* font_pool, VkDescriptorSetLayout* font_layout) {
 | 
					 | 
					 | 
					 | 
					VkResult create_layer(
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkResult result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorPoolSize font_pool_sizes[] = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorCount = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    },
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorCount = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    },
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorPoolCreateInfo font_pool_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pPoolSizes = font_pool_sizes,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .poolSizeCount = sizeof(font_pool_sizes)/sizeof(VkDescriptorPoolSize),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .maxSets = max_sets,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vkCreateDescriptorPool(device, &font_pool_info, NULL, font_pool);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorSetLayoutBinding font_descriptor_bindings[] = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .binding = 0,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorCount = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    },
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .binding = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorCount = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    },
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorSetLayoutCreateInfo font_descriptor_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pBindings = font_descriptor_bindings,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .bindingCount = sizeof(font_descriptor_bindings)/sizeof(VkDescriptorSetLayoutBinding),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vkCreateDescriptorSetLayout(device, &font_descriptor_info, NULL, font_layout);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					VkResult create_text_pointers(
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    uint32_t max_strings,
 | 
					 | 
					 | 
					 | 
					    uint32_t max_strings,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    uint32_t max_characters,
 | 
					 | 
					 | 
					 | 
					    uint32_t max_characters,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    uint32_t max_rects,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    VkDevice device,
 | 
					 | 
					 | 
					 | 
					    VkDevice device,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    VmaAllocator allocator,
 | 
					 | 
					 | 
					 | 
					    VmaAllocator allocator,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    VkCommandPool transfer_pool,
 | 
					 | 
					 | 
					 | 
					    VkCommandPool transfer_pool,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Queue transfer_queue,
 | 
					 | 
					 | 
					 | 
					    Queue transfer_queue,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TextPointersMemory* memory,
 | 
					 | 
					 | 
					 | 
					    UILayerStorage* memory,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    VkDeviceAddress* address) {
 | 
					 | 
					 | 
					 | 
					    VkDeviceAddress* address) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkResult result;
 | 
					 | 
					 | 
					 | 
					  VkResult result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VmaAllocationCreateInfo memory_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VMA_MEMORY_USAGE_GPU_ONLY,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCreateInfo pointers_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(StringPointers),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &pointers_info, &memory_info, &memory->pointers_buffer, &memory->pointers_memory, NULL);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCreateInfo draw_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(DrawCommand),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &draw_info, &memory_info, &memory->draw_buffer, &memory->draw_memory, NULL);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCreateInfo strings_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = max_strings*sizeof(String),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &strings_info, &memory_info, &memory->strings_buffer, &memory->strings_memory, NULL);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCreateInfo codes_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = max_characters*sizeof(DrawCommand),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &codes_info, &memory_info, &memory->codes_buffer, &memory->codes_memory, NULL);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCreateInfo characters_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = max_characters*sizeof(DrawCommand),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &characters_info, &memory_info, &memory->characters_buffer, &memory->characters_memory, NULL);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferDeviceAddressInfo pointers_address = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .buffer = memory->pointers_buffer,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferDeviceAddressInfo strings_address = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .buffer = memory->strings_buffer,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferDeviceAddressInfo codes_address = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .buffer = memory->codes_buffer,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferDeviceAddressInfo characters_address = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .buffer = memory->characters_buffer,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferDeviceAddressInfo draw_address = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .buffer = memory->draw_buffer,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBuffer temp_buffer;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VmaAllocation temp_memory;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCreateInfo temp_buffer_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(StringPointers) +
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            sizeof(DrawCommand),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VmaAllocationCreateInfo temp_memory_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &temp_buffer_info, &temp_memory_info, &temp_buffer, &temp_memory, NULL);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  void* mapped;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaMapMemory(allocator, temp_memory, &mapped);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  DrawCommand draw = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .vertex_count = 6,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  memcpy(mapped + 0, &draw, sizeof(DrawCommand));
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  StringPointers pointers = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .strings = vkGetBufferDeviceAddress(device, &strings_address),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .codes = vkGetBufferDeviceAddress(device, &codes_address),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .characters = vkGetBufferDeviceAddress(device, &characters_address),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .draw = vkGetBufferDeviceAddress(device, &draw_address),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  memcpy(mapped + sizeof(DrawCommand), &pointers, sizeof(StringPointers));
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vmaUnmapMemory(allocator, temp_memory);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCopy copy_draw = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(DrawCommand),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .srcOffset = 0,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vkCmdCopyBuffer(command_buffer, temp_buffer, memory->draw_buffer, 1, ©_draw);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCopy copy_pointers = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(StringPointers),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .srcOffset = sizeof(DrawCommand),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vkCmdCopyBuffer(command_buffer, temp_buffer, memory->pointers_buffer, 1, ©_pointers);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = command_end_single(device, command_buffer, transfer_pool, transfer_queue);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vmaDestroyBuffer(allocator, temp_buffer, temp_memory);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  *address = vkGetBufferDeviceAddress(device, &pointers_address);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayout layout, VkDescriptorPool pool,VkCommandPool transfer_pool, Queue transfer_queue, FT_Library library, const char* ttf_file, uint32_t size, VkBool32 antialias, uint32_t** charmap, Font* descriptor) {  
 | 
					 | 
					 | 
					 | 
					VkResult load_font(
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    VkDevice device,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    VmaAllocator allocator,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    VkBuffer font_infos,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    VkDescriptorSet font_samplers,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    VkDescriptorSet font_textures,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    uint32_t index,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    VkCommandPool transfer_pool,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    Queue transfer_queue,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    FT_Library library,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    const char* ttf_file,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    uint32_t size,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    VkBool32 antialias,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    uint32_t** charmap,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    FontStorage* memory) {  
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  FT_Face face;
 | 
					 | 
					 | 
					 | 
					  FT_Face face;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  int error;
 | 
					 | 
					 | 
					 | 
					  int error;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -572,7 +381,7 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uint32_t* tmp_charmap = malloc(sizeof(uint32_t)*face->num_glyphs);
 | 
					 | 
					 | 
					 | 
					  uint32_t* tmp_charmap = malloc(sizeof(uint32_t)*face->num_glyphs);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  SymbolInfo* symbols = malloc(sizeof(SymbolInfo)*face->num_glyphs);
 | 
					 | 
					 | 
					 | 
					  SymbolInfo* symbols = malloc(sizeof(SymbolInfo)*face->num_glyphs);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  FontUniform uniform;
 | 
					 | 
					 | 
					 | 
					  Font info;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uint32_t glyph_index;
 | 
					 | 
					 | 
					 | 
					  uint32_t glyph_index;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uint32_t max_height = 0;
 | 
					 | 
					 | 
					 | 
					  uint32_t max_height = 0;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -607,9 +416,9 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    c = FT_Get_Next_Char(face, c, &glyph_index);
 | 
					 | 
					 | 
					 | 
					    c = FT_Get_Next_Char(face, c, &glyph_index);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uniform.width = max_width;
 | 
					 | 
					 | 
					 | 
					  info.width = max_width;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uniform.height = max_height;
 | 
					 | 
					 | 
					 | 
					  info.height = max_height;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uniform.num_symbols = symbol_count;
 | 
					 | 
					 | 
					 | 
					  info.num_symbols = symbol_count;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uint32_t image_size = max_width*max_height*sizeof(uint32_t);
 | 
					 | 
					 | 
					 | 
					  uint32_t image_size = max_width*max_height*sizeof(uint32_t);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uint32_t* images = malloc(image_size*symbol_count);
 | 
					 | 
					 | 
					 | 
					  uint32_t* images = malloc(image_size*symbol_count);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  memset(images, 0x00, image_size*symbol_count);
 | 
					 | 
					 | 
					 | 
					  memset(images, 0x00, image_size*symbol_count);
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -636,53 +445,29 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkResult result;
 | 
					 | 
					 | 
					 | 
					  VkResult result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorSetAllocateInfo set_allocate_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pSetLayouts = &layout,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .descriptorSetCount = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .descriptorPool = pool,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vkAllocateDescriptorSets(device, &set_allocate_info, &descriptor->set);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCreateInfo symbol_buffer_info = {
 | 
					 | 
					 | 
					 | 
					  VkBufferCreateInfo symbol_buffer_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
 | 
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(SymbolInfo)*uniform.num_symbols,
 | 
					 | 
					 | 
					 | 
					    .size = sizeof(SymbolInfo)*info.num_symbols,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VmaAllocationCreateInfo symbol_memory_info = {
 | 
					 | 
					 | 
					 | 
					  VmaAllocationCreateInfo symbol_memory_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VMA_MEMORY_USAGE_GPU_ONLY,
 | 
					 | 
					 | 
					 | 
					    .usage = VMA_MEMORY_USAGE_GPU_ONLY,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &symbol_buffer_info, &symbol_memory_info, &descriptor->symbols, &descriptor->symbol_memory, NULL);
 | 
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &symbol_buffer_info, &symbol_memory_info, &memory->symbols, &memory->symbol_memory, NULL);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCreateInfo uniform_buffer_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(FontUniform),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VmaAllocationCreateInfo uniform_memory_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VMA_MEMORY_USAGE_GPU_ONLY,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &uniform_buffer_info, &uniform_memory_info, &descriptor->uniform, &descriptor->uniform_memory, NULL);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkImageCreateInfo image_info = {
 | 
					 | 
					 | 
					 | 
					  VkImageCreateInfo image_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
 | 
					 | 
					 | 
					 | 
					    .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .extent.depth  = 1,
 | 
					 | 
					 | 
					 | 
					    .extent.depth  = 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .extent.width  = uniform.width,
 | 
					 | 
					 | 
					 | 
					    .extent.width  = info.width,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .extent.height = uniform.height,
 | 
					 | 
					 | 
					 | 
					    .extent.height = info.height,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .mipLevels = 1,
 | 
					 | 
					 | 
					 | 
					    .mipLevels = 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .arrayLayers = uniform.num_symbols,
 | 
					 | 
					 | 
					 | 
					    .arrayLayers = info.num_symbols,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .format = VK_FORMAT_R8G8B8A8_SRGB,
 | 
					 | 
					 | 
					 | 
					    .format = VK_FORMAT_R8G8B8A8_SRGB,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .tiling = VK_IMAGE_TILING_OPTIMAL,
 | 
					 | 
					 | 
					 | 
					    .tiling = VK_IMAGE_TILING_OPTIMAL,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
 | 
					 | 
					 | 
					 | 
					    .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -694,7 +479,7 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VMA_MEMORY_USAGE_GPU_ONLY,
 | 
					 | 
					 | 
					 | 
					    .usage = VMA_MEMORY_USAGE_GPU_ONLY,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaCreateImage(allocator, &image_info, &image_memory_info, &descriptor->image, &descriptor->image_memory, NULL);
 | 
					 | 
					 | 
					 | 
					  result = vmaCreateImage(allocator, &image_info, &image_memory_info, &memory->image, &memory->image_memory, NULL);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -703,7 +488,7 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
 | 
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(FontUniform) + image_size*uniform.num_symbols + sizeof(SymbolInfo)*uniform.num_symbols,
 | 
					 | 
					 | 
					 | 
					    .size = sizeof(Font) + image_size*info.num_symbols + sizeof(SymbolInfo)*info.num_symbols,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VmaAllocationCreateInfo staging_memory_info = {
 | 
					 | 
					 | 
					 | 
					  VmaAllocationCreateInfo staging_memory_info = {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -722,66 +507,66 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  memcpy(mapped_staging + image_size*uniform.num_symbols + sizeof(FontUniform), symbols, sizeof(SymbolInfo)*uniform.num_symbols);
 | 
					 | 
					 | 
					 | 
					  memcpy(mapped_staging + image_size*info.num_symbols + sizeof(Font), symbols, sizeof(SymbolInfo)*info.num_symbols);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferDeviceAddressInfo address_info = {
 | 
					 | 
					 | 
					 | 
					  VkBufferDeviceAddressInfo address_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .buffer = descriptor->symbols,
 | 
					 | 
					 | 
					 | 
					    .buffer = memory->symbols,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						uniform.symbol_list = vkGetBufferDeviceAddress(device, &address_info);
 | 
					 | 
					 | 
					 | 
						info.symbol_list = vkGetBufferDeviceAddress(device, &address_info);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  memcpy(mapped_staging + image_size*uniform.num_symbols, &uniform, sizeof(FontUniform));
 | 
					 | 
					 | 
					 | 
					  memcpy(mapped_staging + image_size*info.num_symbols, &info, sizeof(Font));
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  memcpy(mapped_staging, images, image_size*uniform.num_symbols);
 | 
					 | 
					 | 
					 | 
					  memcpy(mapped_staging, images, image_size*info.num_symbols);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vmaUnmapMemory(allocator, staging_memory);
 | 
					 | 
					 | 
					 | 
					  vmaUnmapMemory(allocator, staging_memory);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  free(images);
 | 
					 | 
					 | 
					 | 
					  free(images);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  free(symbols);
 | 
					 | 
					 | 
					 | 
					  free(symbols);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);
 | 
					 | 
					 | 
					 | 
					  VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCopy uniform_copy_info = {
 | 
					 | 
					 | 
					 | 
					  VkBufferCopy info_copy = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(FontUniform),
 | 
					 | 
					 | 
					 | 
					    .size = sizeof(Font),
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .srcOffset = image_size*uniform.num_symbols,
 | 
					 | 
					 | 
					 | 
					    .srcOffset = image_size*info.num_symbols,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .dstOffset = 0,
 | 
					 | 
					 | 
					 | 
					    .dstOffset = index*sizeof(Font),
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vkCmdCopyBuffer(command_buffer, staging_buffer, descriptor->uniform, 1, &uniform_copy_info);
 | 
					 | 
					 | 
					 | 
					  vkCmdCopyBuffer(command_buffer, staging_buffer, font_infos, 1, &info_copy);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCopy symbol_copy_info = {
 | 
					 | 
					 | 
					 | 
					  VkBufferCopy symbol_copy = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(SymbolInfo)*uniform.num_symbols,
 | 
					 | 
					 | 
					 | 
					    .size = sizeof(SymbolInfo)*info.num_symbols,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .srcOffset = image_size*uniform.num_symbols + sizeof(FontUniform),
 | 
					 | 
					 | 
					 | 
					    .srcOffset = image_size*info.num_symbols + sizeof(Font),
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .dstOffset = 0,
 | 
					 | 
					 | 
					 | 
					    .dstOffset = 0,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vkCmdCopyBuffer(command_buffer, staging_buffer, descriptor->symbols, 1, &symbol_copy_info);
 | 
					 | 
					 | 
					 | 
					  vkCmdCopyBuffer(command_buffer, staging_buffer, memory->symbols, 1, &symbol_copy);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkImageMemoryBarrier first_barrier = {
 | 
					 | 
					 | 
					 | 
					  VkImageMemoryBarrier first_barrier = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .image = descriptor->image,
 | 
					 | 
					 | 
					 | 
					    .image = memory->image,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
 | 
					 | 
					 | 
					 | 
					    .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
 | 
					 | 
					 | 
					 | 
					    .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
 | 
					 | 
					 | 
					 | 
					    .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
 | 
					 | 
					 | 
					 | 
					    .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
					 | 
					 | 
					 | 
					    .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .subresourceRange.levelCount = 1,
 | 
					 | 
					 | 
					 | 
					    .subresourceRange.levelCount = 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .subresourceRange.layerCount = uniform.num_symbols,
 | 
					 | 
					 | 
					 | 
					    .subresourceRange.layerCount = info.num_symbols,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .srcAccessMask = 0,
 | 
					 | 
					 | 
					 | 
					    .srcAccessMask = 0,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
 | 
					 | 
					 | 
					 | 
					    .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &first_barrier);
 | 
					 | 
					 | 
					 | 
					  vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &first_barrier);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferImageCopy image_copy = {
 | 
					 | 
					 | 
					 | 
					  VkBufferImageCopy image_copy = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .imageSubresource.layerCount = uniform.num_symbols,
 | 
					 | 
					 | 
					 | 
					    .imageSubresource.layerCount = info.num_symbols,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
					 | 
					 | 
					 | 
					    .imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .imageExtent = image_info.extent,
 | 
					 | 
					 | 
					 | 
					    .imageExtent = image_info.extent,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vkCmdCopyBufferToImage(command_buffer, staging_buffer, descriptor->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy);
 | 
					 | 
					 | 
					 | 
					  vkCmdCopyBufferToImage(command_buffer, staging_buffer, memory->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkImageMemoryBarrier second_barrier = {
 | 
					 | 
					 | 
					 | 
					  VkImageMemoryBarrier second_barrier = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .image = descriptor->image,
 | 
					 | 
					 | 
					 | 
					    .image = memory->image,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
 | 
					 | 
					 | 
					 | 
					    .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
 | 
					 | 
					 | 
					 | 
					    .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
 | 
					 | 
					 | 
					 | 
					    .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
 | 
					 | 
					 | 
					 | 
					    .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
					 | 
					 | 
					 | 
					    .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .subresourceRange.levelCount = 1,
 | 
					 | 
					 | 
					 | 
					    .subresourceRange.levelCount = 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .subresourceRange.layerCount = uniform.num_symbols,
 | 
					 | 
					 | 
					 | 
					    .subresourceRange.layerCount = info.num_symbols,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
 | 
					 | 
					 | 
					 | 
					    .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
 | 
					 | 
					 | 
					 | 
					    .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -795,18 +580,18 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkImageViewCreateInfo view_info = {
 | 
					 | 
					 | 
					 | 
					  VkImageViewCreateInfo view_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .image = descriptor->image,
 | 
					 | 
					 | 
					 | 
					    .image = memory->image,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
 | 
					 | 
					 | 
					 | 
					    .viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .format = VK_FORMAT_R8G8B8A8_SRGB,
 | 
					 | 
					 | 
					 | 
					    .format = VK_FORMAT_R8G8B8A8_SRGB,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .subresourceRange = {
 | 
					 | 
					 | 
					 | 
					    .subresourceRange = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
					 | 
					 | 
					 | 
					      .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .layerCount = uniform.num_symbols,
 | 
					 | 
					 | 
					 | 
					      .layerCount = info.num_symbols,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .baseMipLevel = 0,
 | 
					 | 
					 | 
					 | 
					      .baseMipLevel = 0,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .levelCount = 1,
 | 
					 | 
					 | 
					 | 
					      .levelCount = 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .baseArrayLayer = 0,
 | 
					 | 
					 | 
					 | 
					      .baseArrayLayer = 0,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    },
 | 
					 | 
					 | 
					 | 
					    },
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vkCreateImageView(device, &view_info, NULL, &descriptor->view);
 | 
					 | 
					 | 
					 | 
					  result = vkCreateImageView(device, &view_info, NULL, &memory->view);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -819,171 +604,199 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
 | 
					 | 
					 | 
					 | 
					    .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
 | 
					 | 
					 | 
					 | 
					    .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vkCreateSampler(device, &sampler_info, NULL, &descriptor->sampler);
 | 
					 | 
					 | 
					 | 
					  result = vkCreateSampler(device, &sampler_info, NULL, &memory->sampler);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorBufferInfo desc_uniform_info = {
 | 
					 | 
					 | 
					 | 
					  VkDescriptorImageInfo desc_sampler_info = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .offset = 0,
 | 
					 | 
					 | 
					 | 
					    .sampler = memory->sampler,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .range = sizeof(FontUniform),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .buffer = descriptor->uniform,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorImageInfo desc_image_info = {
 | 
					 | 
					 | 
					 | 
					  VkDescriptorImageInfo desc_texture_info = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sampler = descriptor->sampler,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
 | 
					 | 
					 | 
					 | 
					    .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .imageView = descriptor->view,
 | 
					 | 
					 | 
					 | 
					    .imageView = memory->view,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkWriteDescriptorSet descriptor_writes[] = {
 | 
					 | 
					 | 
					 | 
					  VkWriteDescriptorSet descriptor_writes[] = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    {
 | 
					 | 
					 | 
					 | 
					    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
 | 
					 | 
					 | 
					 | 
					      .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .dstSet = descriptor->set,
 | 
					 | 
					 | 
					 | 
					      .dstSet = font_textures,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .dstBinding = 0,
 | 
					 | 
					 | 
					 | 
					      .dstBinding = 0,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .dstArrayElement = 0,
 | 
					 | 
					 | 
					 | 
					      .dstArrayElement = index,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
 | 
					 | 
					 | 
					 | 
					      .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorCount = 1,
 | 
					 | 
					 | 
					 | 
					      .descriptorCount = 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .pBufferInfo = &desc_uniform_info,
 | 
					 | 
					 | 
					 | 
					      .pImageInfo = &desc_texture_info,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    },
 | 
					 | 
					 | 
					 | 
					    },
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    {
 | 
					 | 
					 | 
					 | 
					    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
 | 
					 | 
					 | 
					 | 
					      .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .dstSet = descriptor->set,
 | 
					 | 
					 | 
					 | 
					      .dstSet = font_samplers,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .dstBinding = 1,
 | 
					 | 
					 | 
					 | 
					      .dstBinding = 0,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
 | 
					 | 
					 | 
					 | 
					      .dstArrayElement = index,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorCount = 1,
 | 
					 | 
					 | 
					 | 
					      .descriptorCount = 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .pImageInfo = &desc_image_info,
 | 
					 | 
					 | 
					 | 
					      .pImageInfo = &desc_sampler_info,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    },
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vkUpdateDescriptorSets(device, 2, descriptor_writes, 0, NULL);
 | 
					 | 
					 | 
					 | 
					  vkUpdateDescriptorSets(device, sizeof(descriptor_writes)/sizeof(VkWriteDescriptorSet), descriptor_writes, 0, NULL);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					VkResult create_ui_descriptor_set(VkDevice device, VmaAllocator allocator, VkExtent2D swapchain_extent, vec2 window_scale, VkDescriptorSetLayout* ui_descriptor_layout, VkDescriptorPool* ui_descriptor_pool, VkDescriptorSet* ui_descriptor_set, VmaAllocation* ui_descriptor_memory, VkBuffer* ui_descriptor_buffer) { 
 | 
					 | 
					 | 
					 | 
					VkResult create_ui_descriptor(VkDevice device, VmaAllocator allocator, uint32_t max_fonts, VkBuffer* font_infos, VmaAllocation* font_infos_memory, VkDescriptorSet* font_samplers, VkDescriptorSet* font_textures, VkDescriptorSetLayout* font_sampler_layout, VkDescriptorSetLayout* font_texture_layout, VkDescriptorPool* font_pool) { 
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorSetLayoutBinding ui_descriptor_bindings[] = {
 | 
					 | 
					 | 
					 | 
					  VkBufferCreateInfo font_infos_buffer = {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .size = sizeof(Font)*max_fonts,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  VmaAllocationCreateInfo font_infos_memory_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .usage = VMA_MEMORY_USAGE_GPU_ONLY,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  VkResult result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &font_infos_buffer, &font_infos_memory_info, font_infos, font_infos_memory, NULL);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  VkDescriptorSetLayoutBinding font_sampler_bindings[] = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    {
 | 
					 | 
					 | 
					 | 
					    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .binding = 0,
 | 
					 | 
					 | 
					 | 
					      .binding = 0,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
 | 
					 | 
					 | 
					 | 
					      .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .descriptorCount = 1,
 | 
					 | 
					 | 
					 | 
					      .descriptorCount = max_fonts,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
 | 
					 | 
					 | 
					 | 
					      .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    },
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  VkDescriptorBindingFlags bindless_flags[] = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  VkDescriptorSetLayoutBindingFlagsCreateInfo font_sampler_bindings_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .bindingCount = sizeof(font_sampler_bindings)/sizeof(VkDescriptorSetLayoutBinding),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pBindingFlags = bindless_flags,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorSetLayoutCreateInfo ui_descriptor_info = {
 | 
					 | 
					 | 
					 | 
					  VkDescriptorSetLayoutCreateInfo font_sampler_info = {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pBindings = ui_descriptor_bindings,
 | 
					 | 
					 | 
					 | 
					    .pBindings = font_sampler_bindings,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .bindingCount = sizeof(ui_descriptor_bindings)/sizeof(VkDescriptorSetLayoutBinding),
 | 
					 | 
					 | 
					 | 
					    .bindingCount = sizeof(font_sampler_bindings)/sizeof(VkDescriptorSetLayoutBinding),
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pNext = &font_sampler_bindings_info,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }; 
 | 
					 | 
					 | 
					 | 
					  }; 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkResult result;
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vkCreateDescriptorSetLayout(device, &ui_descriptor_info, NULL, ui_descriptor_layout);
 | 
					 | 
					 | 
					 | 
					  result = vkCreateDescriptorSetLayout(device, &font_sampler_info, NULL, font_sampler_layout);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorPoolSize pool_size = {
 | 
					 | 
					 | 
					 | 
					  VkDescriptorSetLayoutBinding font_texture_bindings[] = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
 | 
					 | 
					 | 
					 | 
					    {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .descriptorCount = 1,
 | 
					 | 
					 | 
					 | 
					      .binding = 0,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      .descriptorCount = max_fonts,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    },
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorPoolCreateInfo ui_pool_info = {
 | 
					 | 
					 | 
					 | 
					  VkDescriptorSetLayoutBindingFlagsCreateInfo font_texture_bindings_info = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pPoolSizes = &pool_size,
 | 
					 | 
					 | 
					 | 
					    .bindingCount = sizeof(font_texture_bindings)/sizeof(VkDescriptorSetLayoutBinding),
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .poolSizeCount = 1,
 | 
					 | 
					 | 
					 | 
					    .pBindingFlags = bindless_flags,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .maxSets = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vkCreateDescriptorPool(device, &ui_pool_info, NULL, ui_descriptor_pool);
 | 
					 | 
					 | 
					 | 
					  VkDescriptorSetLayoutCreateInfo font_texture_info = {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pBindings = font_texture_bindings,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .bindingCount = sizeof(font_texture_bindings)/sizeof(VkDescriptorSetLayoutBinding),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pNext = &font_texture_bindings_info,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  }; 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  result = vkCreateDescriptorSetLayout(device, &font_texture_info, NULL, font_texture_layout);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorSetAllocateInfo ui_descriptor_allocate_info = {
 | 
					 | 
					 | 
					 | 
					  VkDescriptorPoolSize font_pool_sizes[] = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
 | 
					 | 
					 | 
					 | 
					    {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pSetLayouts = ui_descriptor_layout,
 | 
					 | 
					 | 
					 | 
					      .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .descriptorSetCount = 1,
 | 
					 | 
					 | 
					 | 
					      .descriptorCount = max_fonts,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .descriptorPool = *ui_descriptor_pool,
 | 
					 | 
					 | 
					 | 
					    },
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      .type = VK_DESCRIPTOR_TYPE_SAMPLER,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      .descriptorCount = max_fonts,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    },
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  VkDescriptorPoolCreateInfo font_pool_info = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pPoolSizes = font_pool_sizes,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .poolSizeCount = 2,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .maxSets = 2,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vkAllocateDescriptorSets(device, &ui_descriptor_allocate_info, ui_descriptor_set);
 | 
					 | 
					 | 
					 | 
					  result = vkCreateDescriptorPool(device, &font_pool_info, NULL, font_pool);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkBufferCreateInfo ui_uniform_buffer_info = {
 | 
					 | 
					 | 
					 | 
					  uint32_t max_font_binding = max_fonts - 1;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
					 | 
					 | 
					  VkDescriptorSetVariableDescriptorCountAllocateInfo count_info = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .size = sizeof(UIUniform),
 | 
					 | 
					 | 
					 | 
					    .descriptorSetCount = 1,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
					 | 
					 | 
					    .pDescriptorCounts = &max_font_binding,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VmaAllocationCreateInfo ui_uniform_memory_info = {
 | 
					 | 
					 | 
					 | 
					  VkDescriptorSetAllocateInfo allocate_font_samplers = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pSetLayouts = font_sampler_layout,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .descriptorSetCount = 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .descriptorPool = *font_pool,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pNext = &count_info,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaCreateBuffer(allocator, &ui_uniform_buffer_info, &ui_uniform_memory_info, ui_descriptor_buffer, ui_descriptor_memory, NULL);
 | 
					 | 
					 | 
					 | 
					  VkDescriptorSetAllocateInfo allocate_font_textures = {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pSetLayouts = font_texture_layout,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .descriptorSetCount = 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .descriptorPool = *font_pool,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    .pNext = &count_info,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  result = vkAllocateDescriptorSets(device, &allocate_font_samplers, font_samplers);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  void* mapped;
 | 
					 | 
					 | 
					 | 
					  result = vkAllocateDescriptorSets(device, &allocate_font_textures, font_textures);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = vmaMapMemory(allocator, *ui_descriptor_memory, &mapped);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  UIUniform ui_uniform;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vec3 screen_offset = {-1.0, -1.0, 0.0};
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vec3 screen_scale = {1.0/(float)swapchain_extent.width*window_scale[0], 1.0/(float)swapchain_extent.height*window_scale[1], 1.0};
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  glm_mat4_identity(ui_uniform.screen);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  glm_translate(ui_uniform.screen, screen_offset);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  glm_scale(ui_uniform.screen, screen_scale);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  memcpy(mapped, &ui_uniform, sizeof(ui_uniform));
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vmaUnmapMemory(allocator, *ui_descriptor_memory);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkDescriptorBufferInfo ui_uniform_info = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .offset = 0,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .range = sizeof(ui_uniform),
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .buffer = *ui_descriptor_buffer,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkWriteDescriptorSet ui_uniform_write = {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .dstSet = *ui_descriptor_set,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .dstBinding = 0,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .dstArrayElement = 0,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .descriptorCount = 1,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    .pBufferInfo = &ui_uniform_info,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  };
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  vkUpdateDescriptorSets(device, 1, &ui_uniform_write, 0, NULL);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					VkResult init_pipelines(VkDevice device, VmaAllocator allocator, VkExtent2D swapchain_extent, vec2 window_scale, VkRenderPass render_pass, UIContext* context) {
 | 
					 | 
					 | 
					 | 
					VkResult create_ui_context(VkDevice device, VmaAllocator allocator, VkRenderPass render_pass, UIContextStorage* memory) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VkResult result;
 | 
					 | 
					 | 
					 | 
					  VkResult result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = create_ui_descriptor_set(device, allocator, swapchain_extent, window_scale, &context->ui_descriptor_layout, &context->ui_descriptor_pool, &context->ui_descriptor_set, &context->ui_descriptor_memory, &context->ui_descriptor_buffer);
 | 
					 | 
					 | 
					 | 
					  result = create_ui_descriptor(device, allocator, 10, &memory->font_infos, &memory->font_infos_memory, &memory->font_samplers, &memory->font_textures, &memory->font_samplers_layout, &memory->font_textures_layout, &memory->fonts_pool);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = create_ui_colored_rect_pipeline(device, render_pass, context->ui_descriptor_layout, &context->ui_pipeline_rect);
 | 
					 | 
					 | 
					 | 
					  result = create_ui_rect_pipeline(device, render_pass, memory->font_samplers_layout, memory->font_textures_layout, &memory->rect_pipeline);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = create_font_descriptor_pools(device, 10, &context->font_pool, &context->font_layout);
 | 
					 | 
					 | 
					 | 
					  result = create_ui_text_pipeline(device, render_pass, memory->font_samplers_layout, memory->font_textures_layout, &memory->char_pipeline, &memory->string_pipeline);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					    return result;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  result = create_ui_text_pipeline(device, render_pass, context->ui_descriptor_layout, context->font_layout, &context->ui_pipeline_text, &context->ui_compute_text);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(result != VK_SUCCESS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return result;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
					 | 
					 | 
					 | 
					  return VK_SUCCESS;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					 | 
					
 
 |