|  |  |  | @ -16,7 +16,63 @@ typedef struct ClientContextStruct { | 
		
	
		
			
				|  |  |  |  |   UIContext ui; | 
		
	
		
			
				|  |  |  |  | } ClientContext; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult test_ui(RenderContext* render, UIContext* ui) { | 
		
	
		
			
				|  |  |  |  | void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui_context) { | 
		
	
		
			
				|  |  |  |  |   UIPushConstant push = { | 
		
	
		
			
				|  |  |  |  |     .time = 0.0, | 
		
	
		
			
				|  |  |  |  |     .layer = 0, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->string_pipeline.pipeline); | 
		
	
		
			
				|  |  |  |  |   for(uint32_t i = 0; i < ui_context->max_containers; i++) { | 
		
	
		
			
				|  |  |  |  |     if(ui_context->containers[i].id != 0x00000000) { | 
		
	
		
			
				|  |  |  |  |       for(uint32_t j = 0; j < ui_context->containers[i].layer_count; j++) { | 
		
	
		
			
				|  |  |  |  |         push.layer = ui_context->containers[i].layers[j].address; | 
		
	
		
			
				|  |  |  |  |         VkBufferMemoryBarrier draw_command_barrier_1 = { | 
		
	
		
			
				|  |  |  |  |           .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, | 
		
	
		
			
				|  |  |  |  |           .buffer = ui_context->containers[i].layers[j].layer, | 
		
	
		
			
				|  |  |  |  |           .offset = offsetof(GPULayer, draw), | 
		
	
		
			
				|  |  |  |  |           .size = sizeof(DrawCommand), | 
		
	
		
			
				|  |  |  |  |           .srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, | 
		
	
		
			
				|  |  |  |  |           .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT, | 
		
	
		
			
				|  |  |  |  |         }; | 
		
	
		
			
				|  |  |  |  |         vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, &draw_command_barrier_1, 0, NULL); | 
		
	
		
			
				|  |  |  |  |         command_copy_buffer(command_buffer, ui_context->containers[i].layers[j].layer, ui_context->containers[i].layers[j].layer, offsetof(GPULayer, num_drawables), offsetof(GPULayer, draw) + offsetof(DrawCommand, instance_count), sizeof(uint32_t)); | 
		
	
		
			
				|  |  |  |  |         VkBufferMemoryBarrier draw_command_barrier_2 = { | 
		
	
		
			
				|  |  |  |  |           .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, | 
		
	
		
			
				|  |  |  |  |           .buffer = ui_context->containers[i].layers[j].layer, | 
		
	
		
			
				|  |  |  |  |           .offset = offsetof(GPULayer, draw), | 
		
	
		
			
				|  |  |  |  |           .size = sizeof(DrawCommand), | 
		
	
		
			
				|  |  |  |  |           .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT, | 
		
	
		
			
				|  |  |  |  |           .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT, | 
		
	
		
			
				|  |  |  |  |         }; | 
		
	
		
			
				|  |  |  |  |         vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, NULL, 1, &draw_command_barrier_2, 0, NULL); | 
		
	
		
			
				|  |  |  |  |         vkCmdPushConstants(command_buffer, ui_context->string_pipeline.layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 16, &push); | 
		
	
		
			
				|  |  |  |  |         vkCmdDispatchIndirect(command_buffer, ui_context->containers[i].layers[j].layer, offsetof(GPULayer, dispatch_strings)); | 
		
	
		
			
				|  |  |  |  |         VkBufferMemoryBarrier draw_command_barrier_3 = { | 
		
	
		
			
				|  |  |  |  |           .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, | 
		
	
		
			
				|  |  |  |  |           .buffer = ui_context->containers[i].layers[j].layer, | 
		
	
		
			
				|  |  |  |  |           .offset = offsetof(GPULayer, draw), | 
		
	
		
			
				|  |  |  |  |           .size = sizeof(DrawCommand), | 
		
	
		
			
				|  |  |  |  |           .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, | 
		
	
		
			
				|  |  |  |  |           .dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, | 
		
	
		
			
				|  |  |  |  |         }; | 
		
	
		
			
				|  |  |  |  |         vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0, 0, NULL, 1, &draw_command_barrier_3, 0, NULL); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         VkBufferMemoryBarrier drawables_barrier = { | 
		
	
		
			
				|  |  |  |  |           .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, | 
		
	
		
			
				|  |  |  |  |           .buffer = ui_context->containers[i].layers[j].drawables, | 
		
	
		
			
				|  |  |  |  |           .offset = 0, | 
		
	
		
			
				|  |  |  |  |           .size = sizeof(GPUDrawable)*ui_context->containers[i].layers[j].data.max_drawables, | 
		
	
		
			
				|  |  |  |  |           .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, | 
		
	
		
			
				|  |  |  |  |           .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, | 
		
	
		
			
				|  |  |  |  |         }; | 
		
	
		
			
				|  |  |  |  |         vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, NULL, 1, &drawables_barrier, 0, NULL); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult test_ui(RenderContext* gpu, UIContext* ui) { | 
		
	
		
			
				|  |  |  |  |   VkResult result; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   GPUString context_strings[] = { | 
		
	
	
		
			
				
					|  |  |  | @ -146,10 +202,17 @@ VkResult test_ui(RenderContext* render, UIContext* ui) { | 
		
	
		
			
				|  |  |  |  |     .layers = chat_layers, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_container(&context_info, render, ui)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_container(&map_info, render, ui)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_container(&inventory_info, render, ui)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_container(&chat_info, render, ui)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_container(&context_info, gpu, ui)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_container(&map_info, gpu, ui)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_container(&inventory_info, gpu, ui)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(create_container(&chat_info, gpu, ui)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   for(uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { | 
		
	
		
			
				|  |  |  |  |     VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool); | 
		
	
		
			
				|  |  |  |  |     record_ui_compute(command_buffer, ui); | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(command_end_single(gpu->device, command_buffer, gpu->transfer_pool, gpu->transfer_queue));  | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return VK_SUCCESS; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					|  |  |  | @ -200,7 +263,7 @@ int main_thread(void* data) { | 
		
	
		
			
				|  |  |  |  |   int x = 0; | 
		
	
		
			
				|  |  |  |  |   while(glfwWindowShouldClose(context->window) == 0) { | 
		
	
		
			
				|  |  |  |  |     glfwPollEvents(); | 
		
	
		
			
				|  |  |  |  |     if(x == 0 && glfwGetTime() > 2.0) { | 
		
	
		
			
				|  |  |  |  |     if(x == 0 && glfwGetTime() > 0.0) { | 
		
	
		
			
				|  |  |  |  |       x = 1; | 
		
	
		
			
				|  |  |  |  |       test_ui(&context->render, &context->ui); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					|  |  |  | 
 |