|
|
|
@ -8,17 +8,14 @@
|
|
|
|
|
* - ui_context->containers[*].layers[*].address <- device address
|
|
|
|
|
* Basically, needs to be re-run whenever the number of layers/containers changes
|
|
|
|
|
*/
|
|
|
|
|
void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui_context, double time) {
|
|
|
|
|
UIPushConstant push = {
|
|
|
|
|
.time = (float)time,
|
|
|
|
|
.layer = 0,
|
|
|
|
|
};
|
|
|
|
|
void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui_context) {
|
|
|
|
|
VkDeviceAddress push[2] = {ui_context->address, 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;
|
|
|
|
|
push[1] = 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,
|
|
|
|
@ -38,7 +35,7 @@ void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui_context, do
|
|
|
|
|
.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);
|
|
|
|
|
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,
|
|
|
|
@ -71,11 +68,8 @@ void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui_context, do
|
|
|
|
|
* - ui_context->containers[*].layers[*].address <- device address
|
|
|
|
|
* Basically, needs to be re-run whenever the number of layers/containers changes
|
|
|
|
|
*/
|
|
|
|
|
void record_ui_draw(VkCommandBuffer command_buffer, UIContext* ui_context, double time) {
|
|
|
|
|
UIPushConstant push = {
|
|
|
|
|
.time = (float)time,
|
|
|
|
|
.layer = 0,
|
|
|
|
|
};
|
|
|
|
|
void record_ui_draw(VkCommandBuffer command_buffer, UIContext* ui_context) {
|
|
|
|
|
VkDeviceAddress push[2] = {ui_context->address, 0};
|
|
|
|
|
|
|
|
|
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.pipeline);
|
|
|
|
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 0, 1, &ui_context->font_samplers, 0, NULL);
|
|
|
|
@ -85,18 +79,71 @@ void record_ui_draw(VkCommandBuffer command_buffer, UIContext* ui_context, doubl
|
|
|
|
|
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;
|
|
|
|
|
vkCmdPushConstants(command_buffer, ui_context->pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, &push);
|
|
|
|
|
push[1] = ui_context->containers[i].layers[j].address;
|
|
|
|
|
vkCmdPushConstants(command_buffer, ui_context->pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, push);
|
|
|
|
|
vkCmdDrawIndirect(command_buffer, ui_context->containers[i].layers[j].layer, offsetof(GPULayer, draw), 1, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult record_draw_commands(
|
|
|
|
|
RenderContext* context,
|
|
|
|
|
UIContext* ui_context) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
for(uint32_t image_index = 0; image_index < context->swapchain_image_count; image_index++) {
|
|
|
|
|
VkCommandBuffer command_buffer = context->swapchain_command_buffers[image_index];
|
|
|
|
|
VK_RESULT(vkResetCommandBuffer(command_buffer, 0));
|
|
|
|
|
|
|
|
|
|
VkCommandBufferBeginInfo begin_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
|
|
|
|
};
|
|
|
|
|
VK_RESULT(vkBeginCommandBuffer(command_buffer, &begin_info));
|
|
|
|
|
|
|
|
|
|
VkViewport viewport = {
|
|
|
|
|
.width = context->swapchain_extent.width,
|
|
|
|
|
.height = context->swapchain_extent.height,
|
|
|
|
|
.maxDepth = 1.0f,
|
|
|
|
|
.minDepth = 0.0f,
|
|
|
|
|
};
|
|
|
|
|
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
|
|
|
|
|
|
|
|
|
|
VkRect2D scissor = {
|
|
|
|
|
.extent = context->swapchain_extent,
|
|
|
|
|
};
|
|
|
|
|
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
|
|
|
|
|
|
|
|
|
VkClearValue clear_values[2] = {{.color={{0.0f, 0.0f, 0.0f, 0.0f}}}, {.depthStencil={1.0f, 0.0f}}};
|
|
|
|
|
|
|
|
|
|
VkRenderPassBeginInfo render_pass_begin = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
|
|
|
|
.renderPass = context->render_pass,
|
|
|
|
|
.framebuffer = context->swapchain_framebuffers[image_index],
|
|
|
|
|
.renderArea.offset = {0, 0},
|
|
|
|
|
.renderArea.extent = context->swapchain_extent,
|
|
|
|
|
.clearValueCount = 2,
|
|
|
|
|
.pClearValues = clear_values,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
record_ui_compute(command_buffer, ui_context);
|
|
|
|
|
vkCmdBeginRenderPass(command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
|
// Render World
|
|
|
|
|
vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
|
// Render UI
|
|
|
|
|
record_ui_draw(command_buffer, ui_context);
|
|
|
|
|
vkCmdEndRenderPass(command_buffer);
|
|
|
|
|
|
|
|
|
|
VK_RESULT(vkEndCommandBuffer(command_buffer));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult draw_frame(
|
|
|
|
|
RenderContext* context,
|
|
|
|
|
UIContext* ui,
|
|
|
|
|
double time) {
|
|
|
|
|
(void)time;
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
result = vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX);
|
|
|
|
@ -115,50 +162,6 @@ VkResult draw_frame(
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkCommandBuffer command_buffer = context->swapchain_command_buffers[image_index];
|
|
|
|
|
VK_RESULT(vkResetCommandBuffer(command_buffer, 0));
|
|
|
|
|
|
|
|
|
|
VkCommandBufferBeginInfo begin_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
|
|
|
|
};
|
|
|
|
|
VK_RESULT(vkBeginCommandBuffer(command_buffer, &begin_info));
|
|
|
|
|
|
|
|
|
|
VkViewport viewport = {
|
|
|
|
|
.width = context->swapchain_extent.width,
|
|
|
|
|
.height = context->swapchain_extent.height,
|
|
|
|
|
.maxDepth = 1.0f,
|
|
|
|
|
.minDepth = 0.0f,
|
|
|
|
|
};
|
|
|
|
|
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
|
|
|
|
|
|
|
|
|
|
VkRect2D scissor = {
|
|
|
|
|
.extent = context->swapchain_extent,
|
|
|
|
|
};
|
|
|
|
|
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
|
|
|
|
|
|
|
|
|
VkClearValue clear_values[2] = {{.color={{0.0f, 0.0f, 0.0f, 0.0f}}}, {.depthStencil={1.0f, 0.0f}}};
|
|
|
|
|
|
|
|
|
|
VkRenderPassBeginInfo render_pass_begin = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
|
|
|
|
.renderPass = context->render_pass,
|
|
|
|
|
.framebuffer = context->swapchain_framebuffers[image_index],
|
|
|
|
|
.renderArea.offset = {0, 0},
|
|
|
|
|
.renderArea.extent = context->swapchain_extent,
|
|
|
|
|
.clearValueCount = 2,
|
|
|
|
|
.pClearValues = clear_values,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
record_ui_compute(command_buffer, ui, time);
|
|
|
|
|
|
|
|
|
|
vkCmdBeginRenderPass(command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
|
// Render World
|
|
|
|
|
vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
|
// Render UI
|
|
|
|
|
record_ui_draw(command_buffer, ui, time);
|
|
|
|
|
vkCmdEndRenderPass(command_buffer);
|
|
|
|
|
|
|
|
|
|
VK_RESULT(vkEndCommandBuffer(command_buffer));
|
|
|
|
|
|
|
|
|
|
VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
|
|
|
|
VkSubmitInfo submit_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
|
|
|
|