|
|
@ -57,7 +57,9 @@ VkResult draw_frame(
|
|
|
|
double time) {
|
|
|
|
double time) {
|
|
|
|
VkResult result;
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
|
|
VkFence fences[] = {context->frame[context->current_frame].ready};
|
|
|
|
FrameContext* frame = &context->frame[context->current_frame];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkFence fences[] = {frame->ready};
|
|
|
|
VK_RESULT(vkWaitForFences(context->device, 1, fences, VK_TRUE, UINT64_MAX));
|
|
|
|
VK_RESULT(vkWaitForFences(context->device, 1, fences, VK_TRUE, UINT64_MAX));
|
|
|
|
VK_RESULT(vkResetFences(context->device, 1, fences));
|
|
|
|
VK_RESULT(vkResetFences(context->device, 1, fences));
|
|
|
|
|
|
|
|
|
|
|
@ -65,28 +67,28 @@ VkResult draw_frame(
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if(context->frame[context->current_frame].transfer_count > 0) {
|
|
|
|
if(frame->transfer_count > 0) {
|
|
|
|
VkCommandBuffer transfer_commands = context->frame[context->current_frame].transfer_commands;
|
|
|
|
VkCommandBuffer transfer_commands = frame->transfer_commands;
|
|
|
|
VK_RESULT(vkResetCommandBuffer(transfer_commands, 0));
|
|
|
|
VK_RESULT(vkResetCommandBuffer(transfer_commands, 0));
|
|
|
|
VK_RESULT(vkBeginCommandBuffer(transfer_commands, &begin_info));
|
|
|
|
VK_RESULT(vkBeginCommandBuffer(transfer_commands, &begin_info));
|
|
|
|
|
|
|
|
|
|
|
|
VkDeviceSize src_offset = 0;
|
|
|
|
VkDeviceSize src_offset = 0;
|
|
|
|
for(uint32_t tid = 0; tid < context->frame[context->current_frame].transfer_count; tid++) {
|
|
|
|
for(uint32_t tid = 0; tid < frame->transfer_count; tid++) {
|
|
|
|
command_copy_buffer(
|
|
|
|
command_copy_buffer(
|
|
|
|
transfer_commands,
|
|
|
|
transfer_commands,
|
|
|
|
context->frame[context->current_frame].transfer_buffer,
|
|
|
|
frame->transfer_buffer,
|
|
|
|
context->frame[context->current_frame].transfer_infos[tid].buffer,
|
|
|
|
frame->transfer_infos[tid].buffer,
|
|
|
|
src_offset,
|
|
|
|
src_offset,
|
|
|
|
context->frame[context->current_frame].transfer_infos[tid].offset,
|
|
|
|
frame->transfer_infos[tid].offset,
|
|
|
|
context->frame[context->current_frame].transfer_infos[tid].size);
|
|
|
|
frame->transfer_infos[tid].size);
|
|
|
|
src_offset += context->frame[context->current_frame].transfer_infos[tid].size;
|
|
|
|
src_offset += frame->transfer_infos[tid].size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VK_RESULT(vkEndCommandBuffer(transfer_commands));
|
|
|
|
VK_RESULT(vkEndCommandBuffer(transfer_commands));
|
|
|
|
VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_TRANSFER_BIT};
|
|
|
|
VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_TRANSFER_BIT};
|
|
|
|
VkSemaphore transfer_signals[] = {context->frame[context->current_frame].transfer};
|
|
|
|
VkSemaphore transfer_signals[] = {frame->transfer};
|
|
|
|
VkSemaphore transfer_waits[] = {context->frame[context->current_frame].frame};
|
|
|
|
VkSemaphore transfer_waits[] = {frame->frame};
|
|
|
|
uint64_t transfer_wait_values[] = {context->frame[context->current_frame].frame_index};
|
|
|
|
uint64_t transfer_wait_values[] = {frame->frame_index};
|
|
|
|
VkTimelineSemaphoreSubmitInfo timeline_info = {
|
|
|
|
VkTimelineSemaphoreSubmitInfo timeline_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
|
|
|
|
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
|
|
|
|
.waitSemaphoreValueCount = sizeof(transfer_wait_values)/sizeof(uint64_t),
|
|
|
|
.waitSemaphoreValueCount = sizeof(transfer_wait_values)/sizeof(uint64_t),
|
|
|
@ -104,20 +106,20 @@ VkResult draw_frame(
|
|
|
|
.pNext = &timeline_info,
|
|
|
|
.pNext = &timeline_info,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
VK_RESULT(vkQueueSubmit(context->transfer_queue.handle, 1, &submit_info, VK_NULL_HANDLE));
|
|
|
|
VK_RESULT(vkQueueSubmit(context->transfer_queue.handle, 1, &submit_info, VK_NULL_HANDLE));
|
|
|
|
context->frame[context->current_frame].transfer_count = 0;
|
|
|
|
frame->transfer_count = 0;
|
|
|
|
context->frame[context->current_frame].transfer_written = 0;
|
|
|
|
frame->transfer_written = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkCommandBuffer compute_commands = context->frame[context->current_frame].compute_commands;
|
|
|
|
VkCommandBuffer compute_commands = frame->compute_commands;
|
|
|
|
VK_RESULT(vkResetCommandBuffer(compute_commands, 0));
|
|
|
|
VK_RESULT(vkResetCommandBuffer(compute_commands, 0));
|
|
|
|
VK_RESULT(vkBeginCommandBuffer(compute_commands, &begin_info));
|
|
|
|
VK_RESULT(vkBeginCommandBuffer(compute_commands, &begin_info));
|
|
|
|
record_ui_compute(compute_commands, ui, context->current_frame);
|
|
|
|
record_ui_compute(compute_commands, ui, context->current_frame);
|
|
|
|
VK_RESULT(vkEndCommandBuffer(compute_commands));
|
|
|
|
VK_RESULT(vkEndCommandBuffer(compute_commands));
|
|
|
|
VkPipelineStageFlags compute_wait_stages[] = {VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT};
|
|
|
|
VkPipelineStageFlags compute_wait_stages[] = {VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT};
|
|
|
|
context->frame[context->current_frame].compute_index += 1;
|
|
|
|
frame->compute_index += 1;
|
|
|
|
VkSemaphore compute_signals[] = {context->frame[context->current_frame].compute};
|
|
|
|
VkSemaphore compute_signals[] = {frame->compute};
|
|
|
|
uint64_t compute_signal_values[] = {context->frame[context->current_frame].compute_index};
|
|
|
|
uint64_t compute_signal_values[] = {frame->compute_index};
|
|
|
|
VkSemaphore compute_waits[] = {context->frame[context->current_frame].transfer};
|
|
|
|
VkSemaphore compute_waits[] = {frame->transfer};
|
|
|
|
VkTimelineSemaphoreSubmitInfo compute_timeline = {
|
|
|
|
VkTimelineSemaphoreSubmitInfo compute_timeline = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
|
|
|
|
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
|
|
|
|
.signalSemaphoreValueCount = sizeof(compute_signal_values)/sizeof(uint64_t),
|
|
|
|
.signalSemaphoreValueCount = sizeof(compute_signal_values)/sizeof(uint64_t),
|
|
|
@ -138,7 +140,7 @@ VkResult draw_frame(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t image_index;
|
|
|
|
uint32_t image_index;
|
|
|
|
result = vkAcquireNextImageKHR(context->device, context->swapchain, UINT64_MAX, context->frame[context->current_frame].image, VK_NULL_HANDLE, &image_index);
|
|
|
|
result = vkAcquireNextImageKHR(context->device, context->swapchain, UINT64_MAX, frame->image, VK_NULL_HANDLE, &image_index);
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -180,11 +182,11 @@ VkResult draw_frame(
|
|
|
|
VK_RESULT(vkEndCommandBuffer(command_buffer));
|
|
|
|
VK_RESULT(vkEndCommandBuffer(command_buffer));
|
|
|
|
|
|
|
|
|
|
|
|
VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT};
|
|
|
|
VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT};
|
|
|
|
VkSemaphore wait_semaphores[] = {context->frame[context->current_frame].image, context->frame[context->current_frame].compute};
|
|
|
|
VkSemaphore wait_semaphores[] = {frame->image, frame->compute};
|
|
|
|
VkSemaphore signal_semaphores[] = {context->frame[context->current_frame].render, context->frame[context->current_frame].frame};
|
|
|
|
VkSemaphore signal_semaphores[] = {frame->render, frame->frame};
|
|
|
|
context->frame[context->current_frame].frame_index += 1;
|
|
|
|
frame->frame_index += 1;
|
|
|
|
uint64_t wait_values[] = {0, context->frame[context->current_frame].compute_index};
|
|
|
|
uint64_t wait_values[] = {0, frame->compute_index};
|
|
|
|
uint64_t signal_values[] = {0, context->frame[context->current_frame].frame_index};
|
|
|
|
uint64_t signal_values[] = {0, frame->frame_index};
|
|
|
|
VkTimelineSemaphoreSubmitInfo timeline_info = {
|
|
|
|
VkTimelineSemaphoreSubmitInfo timeline_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
|
|
|
|
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
|
|
|
|
.signalSemaphoreValueCount = sizeof(signal_values)/sizeof(uint64_t),
|
|
|
|
.signalSemaphoreValueCount = sizeof(signal_values)/sizeof(uint64_t),
|
|
|
@ -204,7 +206,7 @@ VkResult draw_frame(
|
|
|
|
.pNext = &timeline_info,
|
|
|
|
.pNext = &timeline_info,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
result = vkQueueSubmit(context->graphics_queue.handle, 1, &submit_info, context->frame[context->current_frame].ready);
|
|
|
|
result = vkQueueSubmit(context->graphics_queue.handle, 1, &submit_info, frame->ready);
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -212,7 +214,7 @@ VkResult draw_frame(
|
|
|
|
VkPresentInfoKHR present_info = {
|
|
|
|
VkPresentInfoKHR present_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
|
|
|
.waitSemaphoreCount = 1,
|
|
|
|
.waitSemaphoreCount = 1,
|
|
|
|
.pWaitSemaphores = &context->frame[context->current_frame].render,
|
|
|
|
.pWaitSemaphores = &frame->render,
|
|
|
|
.swapchainCount = 1,
|
|
|
|
.swapchainCount = 1,
|
|
|
|
.pSwapchains = &context->swapchain,
|
|
|
|
.pSwapchains = &context->swapchain,
|
|
|
|
.pImageIndices = &image_index,
|
|
|
|
.pImageIndices = &image_index,
|
|
|
|