|  |  |  | @ -85,11 +85,14 @@ VkResult draw_frame( | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(vkEndCommandBuffer(transfer_commands)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     frame->transfer_index += 1; | 
		
	
		
			
				|  |  |  |  |     VkPipelineStageFlags transfer_wait_stages[] = {VK_PIPELINE_STAGE_TRANSFER_BIT}; | 
		
	
		
			
				|  |  |  |  |     VkTimelineSemaphoreSubmitInfo transfer_timeline = { | 
		
	
		
			
				|  |  |  |  |       .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, | 
		
	
		
			
				|  |  |  |  |       .waitSemaphoreValueCount = 1, | 
		
	
		
			
				|  |  |  |  |       .pWaitSemaphoreValues = &frame->frame_index, | 
		
	
		
			
				|  |  |  |  |       .signalSemaphoreValueCount = 1, | 
		
	
		
			
				|  |  |  |  |       .pSignalSemaphoreValues = &frame->transfer_index, | 
		
	
		
			
				|  |  |  |  |     }; | 
		
	
		
			
				|  |  |  |  |     VkSubmitInfo transfer_submit = { | 
		
	
		
			
				|  |  |  |  |       .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, | 
		
	
	
		
			
				
					|  |  |  | @ -107,32 +110,40 @@ VkResult draw_frame( | 
		
	
		
			
				|  |  |  |  |     frame->transfer_written = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     VkCommandBuffer compute_commands = frame->compute_commands; | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(vkResetCommandBuffer(compute_commands, 0)); | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(vkBeginCommandBuffer(compute_commands, &begin_info)); | 
		
	
		
			
				|  |  |  |  |     record_ui_compute(compute_commands, ui, context->current_frame); | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(vkEndCommandBuffer(compute_commands)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     frame->compute_index += 1; | 
		
	
		
			
				|  |  |  |  |     VkPipelineStageFlags compute_wait_stages[] = {VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT}; | 
		
	
		
			
				|  |  |  |  |     VkTimelineSemaphoreSubmitInfo compute_timeline = { | 
		
	
		
			
				|  |  |  |  |       .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, | 
		
	
		
			
				|  |  |  |  |       .signalSemaphoreValueCount = 1, | 
		
	
		
			
				|  |  |  |  |       .pSignalSemaphoreValues = &frame->compute_index, | 
		
	
		
			
				|  |  |  |  |     }; | 
		
	
		
			
				|  |  |  |  |     VkSubmitInfo compute_submit = { | 
		
	
		
			
				|  |  |  |  |       .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, | 
		
	
		
			
				|  |  |  |  |       .commandBufferCount = 1, | 
		
	
		
			
				|  |  |  |  |       .pCommandBuffers = &compute_commands, | 
		
	
		
			
				|  |  |  |  |       .pSignalSemaphores = &frame->compute, | 
		
	
		
			
				|  |  |  |  |       .signalSemaphoreCount = 1, | 
		
	
		
			
				|  |  |  |  |       .pWaitSemaphores = &frame->transfer, | 
		
	
		
			
				|  |  |  |  |       .pWaitDstStageMask = compute_wait_stages, | 
		
	
		
			
				|  |  |  |  |       .waitSemaphoreCount = 1, | 
		
	
		
			
				|  |  |  |  |       .pNext = &compute_timeline, | 
		
	
		
			
				|  |  |  |  |     }; | 
		
	
		
			
				|  |  |  |  |     VK_RESULT(vkQueueSubmit(context->transfer_queue.handle, 1, &compute_submit, VK_NULL_HANDLE)); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   VkCommandBuffer compute_commands = frame->compute_commands; | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(vkResetCommandBuffer(compute_commands, 0)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(vkBeginCommandBuffer(compute_commands, &begin_info)); | 
		
	
		
			
				|  |  |  |  |   VkMemoryBarrier compute_barrier = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, | 
		
	
		
			
				|  |  |  |  |     .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, | 
		
	
		
			
				|  |  |  |  |     .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  |   vkCmdPipelineBarrier(compute_commands, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &compute_barrier, 0, NULL, 0, NULL); | 
		
	
		
			
				|  |  |  |  |   record_ui_compute(compute_commands, ui, context->current_frame); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(vkEndCommandBuffer(compute_commands)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   frame->compute_index += 1; | 
		
	
		
			
				|  |  |  |  |   VkPipelineStageFlags compute_wait_stages[] = {VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}; | 
		
	
		
			
				|  |  |  |  |   VkTimelineSemaphoreSubmitInfo compute_timeline = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, | 
		
	
		
			
				|  |  |  |  |     .waitSemaphoreValueCount = 1, | 
		
	
		
			
				|  |  |  |  |     .pWaitSemaphoreValues = &frame->transfer_index, | 
		
	
		
			
				|  |  |  |  |     .signalSemaphoreValueCount = 1, | 
		
	
		
			
				|  |  |  |  |     .pSignalSemaphoreValues = &frame->compute_index, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  |   VkSubmitInfo compute_submit = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, | 
		
	
		
			
				|  |  |  |  |     .commandBufferCount = 1, | 
		
	
		
			
				|  |  |  |  |     .pCommandBuffers = &compute_commands, | 
		
	
		
			
				|  |  |  |  |     .pSignalSemaphores = &frame->compute, | 
		
	
		
			
				|  |  |  |  |     .signalSemaphoreCount = 1, | 
		
	
		
			
				|  |  |  |  |     .pWaitSemaphores = &frame->transfer, | 
		
	
		
			
				|  |  |  |  |     .pWaitDstStageMask = compute_wait_stages, | 
		
	
		
			
				|  |  |  |  |     .waitSemaphoreCount = 1, | 
		
	
		
			
				|  |  |  |  |     .pNext = &compute_timeline, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(vkQueueSubmit(context->transfer_queue.handle, 1, &compute_submit, VK_NULL_HANDLE)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   uint32_t image_index; | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(vkAcquireNextImageKHR(context->device, context->swapchain, UINT64_MAX, frame->image, VK_NULL_HANDLE, &image_index)); | 
		
	
	
		
			
				
					|  |  |  | 
 |