|  |  |  | @ -309,7 +309,7 @@ VkResult create_container( | 
		
	
		
			
				|  |  |  |  |   memory->layer_count = layer_count; | 
		
	
		
			
				|  |  |  |  |   memory->layers = malloc(sizeof(UILayerStorage)*layer_count); | 
		
	
		
			
				|  |  |  |  |   for(uint32_t i = 0; i < layer_count; i++) { | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(create_layer(i, layers[i].strings, layers[i].codes, layers[i].drawables, layers[i].font, gpu, memory)); | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(create_layer(i, &layers[i], gpu, memory)); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return VK_SUCCESS; | 
		
	
	
		
			
				
					|  |  |  | @ -317,43 +317,40 @@ VkResult create_container( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult create_layer( | 
		
	
		
			
				|  |  |  |  |     uint32_t index, | 
		
	
		
			
				|  |  |  |  |     uint32_t strings, | 
		
	
		
			
				|  |  |  |  |     uint32_t codes, | 
		
	
		
			
				|  |  |  |  |     uint32_t drawables, | 
		
	
		
			
				|  |  |  |  |     uint32_t font, | 
		
	
		
			
				|  |  |  |  |     UILayerInput* input, | 
		
	
		
			
				|  |  |  |  |     RenderContext* gpu, | 
		
	
		
			
				|  |  |  |  |     UIContainerStorage* container) { | 
		
	
		
			
				|  |  |  |  |   VkResult result; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_storage_buffer(gpu->allocator, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, sizeof(UILayer), &container->layers[index].layer, &container->layers[index].layer_memory)); | 
		
	
		
			
				|  |  |  |  |   if(strings > 0) { | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(UIString)*strings, &container->layers[index].strings, &container->layers[index].strings_memory)) | 
		
	
		
			
				|  |  |  |  |   if(input->num_strings > 0) { | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(UIString)*input->num_strings, &container->layers[index].strings, &container->layers[index].strings_memory)) | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   if(codes + drawables > 0) { | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(UIDrawable)*(drawables + codes), &container->layers[index].drawables, &container->layers[index].drawables_memory)); | 
		
	
		
			
				|  |  |  |  |   if(input->num_codes + input->num_drawables > 0) { | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(UIDrawable)*(input->num_drawables + input->num_codes), &container->layers[index].drawables, &container->layers[index].drawables_memory)); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   if(codes > 0) { | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(uint32_t)*codes, &container->layers[index].codes, &container->layers[index].codes_memory)); | 
		
	
		
			
				|  |  |  |  |   if(input->num_codes > 0) { | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(uint32_t)*input->num_codes, &container->layers[index].codes, &container->layers[index].codes_memory)); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkBuffer transfer; | 
		
	
		
			
				|  |  |  |  |   VmaAllocation transfer_memory; | 
		
	
		
			
				|  |  |  |  |   void* mapped; | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_transfer_buffer(gpu->allocator, sizeof(UILayer), &transfer, &transfer_memory, &mapped)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_transfer_buffer(gpu->allocator, sizeof(UILayer) + sizeof(UIString) * input->num_strings + sizeof(UIDrawable)*input->num_drawables + sizeof(uint32_t)*input->num_codes, &transfer, &transfer_memory, &mapped)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if(strings > 0) { | 
		
	
		
			
				|  |  |  |  |   if(input->num_strings > 0) { | 
		
	
		
			
				|  |  |  |  |     container->layers[index].data.strings = buffer_address(gpu->device, container->layers[index].strings); | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     container->layers[index].data.strings = 0x00000000; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if(codes > 0) { | 
		
	
		
			
				|  |  |  |  |   if(input->num_codes > 0) { | 
		
	
		
			
				|  |  |  |  |     container->layers[index].data.codes = buffer_address(gpu->device, container->layers[index].codes); | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     container->layers[index].data.codes = 0x00000000; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if(codes + drawables > 0) { | 
		
	
		
			
				|  |  |  |  |   if(input->num_codes + input->num_drawables > 0) { | 
		
	
		
			
				|  |  |  |  |     container->layers[index].data.drawables = buffer_address(gpu->device, container->layers[index].drawables); | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     container->layers[index].data.drawables = 0x00000000; | 
		
	
	
		
			
				
					|  |  |  | @ -365,29 +362,42 @@ VkResult create_layer( | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.draw.first_instance = 0; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.draw.instance_count = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.dispatch_strings.x = strings; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.dispatch_strings.x = input->num_strings; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.dispatch_strings.y = 1; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.dispatch_strings.z = 1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.font_index = font; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.max_drawables = drawables + codes; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.max_strings = strings; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.num_drawables = drawables; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.font_index = input->font; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.max_drawables = input->num_drawables + input->num_codes; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.max_strings = input->num_strings; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.num_drawables = input->num_drawables; | 
		
	
		
			
				|  |  |  |  |   container->layers[index].data.container = container->address; | 
		
	
		
			
				|  |  |  |  |   memcpy(mapped, &container->layers[index].data, sizeof(UILayer)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool); | 
		
	
		
			
				|  |  |  |  |   command_copy_buffer(command_buffer, transfer, container->layers[index].layer, 0, 0, sizeof(UILayer)); | 
		
	
		
			
				|  |  |  |  |   if(strings > 0) { | 
		
	
		
			
				|  |  |  |  |     vkCmdFillBuffer(command_buffer, container->layers[index].strings, 0, sizeof(UIString)*strings, 0x00000000); | 
		
	
		
			
				|  |  |  |  |   if(input->num_strings > 0) { | 
		
	
		
			
				|  |  |  |  |     UIString* strings = (UIString*)(mapped + sizeof(UILayer)); | 
		
	
		
			
				|  |  |  |  |     for(uint32_t i = 0; i < input->num_strings; i++) { | 
		
	
		
			
				|  |  |  |  |       memcpy(&strings[i], &input->strings[i], sizeof(UIString)); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     command_copy_buffer(command_buffer, transfer, container->layers[index].strings, sizeof(UILayer), 0, sizeof(UIString)*input->num_strings);  | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if(codes + drawables > 0) { | 
		
	
		
			
				|  |  |  |  |     vkCmdFillBuffer(command_buffer, container->layers[index].drawables, 0, sizeof(UIDrawable)*(drawables+codes), 0x00000000); | 
		
	
		
			
				|  |  |  |  |   if(input->num_drawables > 0) { | 
		
	
		
			
				|  |  |  |  |     UIDrawable* drawables = (UIDrawable*)(mapped + sizeof(UILayer) + sizeof(UIString)*input->num_strings); | 
		
	
		
			
				|  |  |  |  |     for(uint32_t i = 0; i < input->num_drawables; i++) { | 
		
	
		
			
				|  |  |  |  |       memcpy(&drawables[i], &input->drawables[i], sizeof(UIDrawable)); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     command_copy_buffer(command_buffer, transfer, container->layers[index].drawables, sizeof(UILayer) + sizeof(UIString)*input->num_strings, 0, sizeof(UIDrawable)*input->num_drawables); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if(codes > 0) { | 
		
	
		
			
				|  |  |  |  |     vkCmdFillBuffer(command_buffer, container->layers[index].codes, 0, sizeof(uint32_t)*codes, 0x00000000); | 
		
	
		
			
				|  |  |  |  |   if(input->num_codes > 0) { | 
		
	
		
			
				|  |  |  |  |     uint32_t* codes = (uint32_t*)(mapped + sizeof(UILayer) + sizeof(UIString)*input->num_strings + sizeof(UIDrawable)*input->num_drawables); | 
		
	
		
			
				|  |  |  |  |     for(uint32_t i = 0; i < input->num_codes; i++) { | 
		
	
		
			
				|  |  |  |  |       codes[i] = input->codes[i]; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     vkCmdFillBuffer(command_buffer, container->layers[index].codes, sizeof(UIDrawable)*input->num_drawables, sizeof(UIDrawable)*input->num_codes, 0x00000000); | 
		
	
		
			
				|  |  |  |  |     command_copy_buffer(command_buffer, transfer, container->layers[index].codes, sizeof(UILayer) + sizeof(UIString)*input->num_strings + sizeof(UIDrawable)*input->num_drawables, 0, sizeof(uint32_t)*input->num_codes); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(command_end_single(gpu->device, command_buffer, gpu->transfer_pool, gpu->transfer_queue)); | 
		
	
		
			
				|  |  |  |  |   vkQueueWaitIdle(gpu->transfer_queue.handle); | 
		
	
	
		
			
				
					|  |  |  | @ -1082,74 +1092,7 @@ VkResult create_ui_context( | 
		
	
		
			
				|  |  |  |  |   return VK_SUCCESS; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void set_ui_rect( | 
		
	
		
			
				|  |  |  |  |     float x, | 
		
	
		
			
				|  |  |  |  |     float y, | 
		
	
		
			
				|  |  |  |  |     float width, | 
		
	
		
			
				|  |  |  |  |     float height, | 
		
	
		
			
				|  |  |  |  |     float r, | 
		
	
		
			
				|  |  |  |  |     float g, | 
		
	
		
			
				|  |  |  |  |     float b, | 
		
	
		
			
				|  |  |  |  |     float a, | 
		
	
		
			
				|  |  |  |  |     UIDrawable* drawable) { | 
		
	
		
			
				|  |  |  |  |   drawable->pos[0] = x; | 
		
	
		
			
				|  |  |  |  |   drawable->pos[1] = y; | 
		
	
		
			
				|  |  |  |  |   drawable->size[0] = width; | 
		
	
		
			
				|  |  |  |  |   drawable->size[1] = height; | 
		
	
		
			
				|  |  |  |  |   drawable->color[0] = r; | 
		
	
		
			
				|  |  |  |  |   drawable->color[1] = g; | 
		
	
		
			
				|  |  |  |  |   drawable->color[2] = b; | 
		
	
		
			
				|  |  |  |  |   drawable->color[3] = a; | 
		
	
		
			
				|  |  |  |  |   drawable->type = 0; | 
		
	
		
			
				|  |  |  |  |   drawable->code = 0; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void set_ui_image( | 
		
	
		
			
				|  |  |  |  |     float x, | 
		
	
		
			
				|  |  |  |  |     float y, | 
		
	
		
			
				|  |  |  |  |     float width, | 
		
	
		
			
				|  |  |  |  |     float height, | 
		
	
		
			
				|  |  |  |  |     float r, | 
		
	
		
			
				|  |  |  |  |     float g, | 
		
	
		
			
				|  |  |  |  |     float b, | 
		
	
		
			
				|  |  |  |  |     float a, | 
		
	
		
			
				|  |  |  |  |     uint32_t index, | 
		
	
		
			
				|  |  |  |  |     UIDrawable* drawable) { | 
		
	
		
			
				|  |  |  |  |   drawable->pos[0] = x; | 
		
	
		
			
				|  |  |  |  |   drawable->pos[1] = y; | 
		
	
		
			
				|  |  |  |  |   drawable->size[0] = width; | 
		
	
		
			
				|  |  |  |  |   drawable->size[1] = height; | 
		
	
		
			
				|  |  |  |  |   drawable->color[0] = r; | 
		
	
		
			
				|  |  |  |  |   drawable->color[1] = g; | 
		
	
		
			
				|  |  |  |  |   drawable->color[2] = b; | 
		
	
		
			
				|  |  |  |  |   drawable->color[3] = a; | 
		
	
		
			
				|  |  |  |  |   drawable->type = 2; | 
		
	
		
			
				|  |  |  |  |   drawable->code = index; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void set_ui_string( | 
		
	
		
			
				|  |  |  |  |     float x, | 
		
	
		
			
				|  |  |  |  |     float y, | 
		
	
		
			
				|  |  |  |  |     float size, | 
		
	
		
			
				|  |  |  |  |     float r, | 
		
	
		
			
				|  |  |  |  |     float g, | 
		
	
		
			
				|  |  |  |  |     float b, | 
		
	
		
			
				|  |  |  |  |     float a, | 
		
	
		
			
				|  |  |  |  |     uint32_t length, | 
		
	
		
			
				|  |  |  |  |     uint32_t offset, | 
		
	
		
			
				|  |  |  |  |     UIString* string) { | 
		
	
		
			
				|  |  |  |  |   string->pos[0] = x; | 
		
	
		
			
				|  |  |  |  |   string->pos[1] = y; | 
		
	
		
			
				|  |  |  |  |   string->size = size; | 
		
	
		
			
				|  |  |  |  |   string->color[0] = r; | 
		
	
		
			
				|  |  |  |  |   string->color[1] = g; | 
		
	
		
			
				|  |  |  |  |   string->color[2] = b; | 
		
	
		
			
				|  |  |  |  |   string->color[3] = a; | 
		
	
		
			
				|  |  |  |  |   string->length = length; | 
		
	
		
			
				|  |  |  |  |   string->offset = offset; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult set_ui_codes( | 
		
	
		
			
				|  |  |  |  | VkResult map_string( | 
		
	
		
			
				|  |  |  |  |     const char * text, | 
		
	
		
			
				|  |  |  |  |     uint32_t* buffer, | 
		
	
		
			
				|  |  |  |  |     uint32_t offset, | 
		
	
	
		
			
				
					|  |  |  | 
 |