|
|
|
@ -16,57 +16,20 @@ typedef struct ClientContextStruct {
|
|
|
|
|
UIContext ui;
|
|
|
|
|
} ClientContext;
|
|
|
|
|
|
|
|
|
|
void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui_context) {
|
|
|
|
|
void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t frame) {
|
|
|
|
|
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);
|
|
|
|
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui->string_pipeline.pipeline);
|
|
|
|
|
for(uint32_t i = 0; i < ui->max_containers; i++) {
|
|
|
|
|
if(ui->containers[i].id != 0x00000000) {
|
|
|
|
|
for(uint32_t j = 0; j < ui->containers[i].layer_count; j++) {
|
|
|
|
|
push.layer = ui->containers[i].layers[j].address[frame];
|
|
|
|
|
command_copy_buffer(command_buffer, ui->containers[i].layers[j].layer[frame], ui->containers[i].layers[j].layer[frame], offsetof(GPULayer, num_drawables), offsetof(GPULayer, draw) + offsetof(DrawCommand, instance_count), sizeof(uint32_t));
|
|
|
|
|
vkCmdPushConstants(command_buffer, ui->string_pipeline.layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 16, &push);
|
|
|
|
|
vkCmdDispatchIndirect(command_buffer, ui->containers[i].layers[j].layer[frame], offsetof(GPULayer, dispatch_strings));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -207,13 +170,6 @@ VkResult test_ui(RenderContext* gpu, UIContext* 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -267,6 +223,36 @@ int main_thread(void* data) {
|
|
|
|
|
x = 1;
|
|
|
|
|
test_ui(&context->render, &context->ui);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
|
|
|
|
VkCommandBuffer command_buffer = command_begin_single(context->render.device, context->render.transfer_pool);
|
|
|
|
|
record_ui_compute(command_buffer, &context->ui, i);
|
|
|
|
|
vkEndCommandBuffer(command_buffer);
|
|
|
|
|
FrameSync id = increment_transfer(&context->render.frame[i].id);
|
|
|
|
|
VkSemaphore wait_semaphores[] = {context->render.frame[i].transfer, context->render.frame[i].frame};
|
|
|
|
|
uint64_t wait_values[] = {id.transfer, id.frame};
|
|
|
|
|
uint64_t signal_values[] = {id.transfer+1};
|
|
|
|
|
VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
|
|
|
|
|
VkTimelineSemaphoreSubmitInfo timeline_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
|
|
|
|
|
.pSignalSemaphoreValues = signal_values,
|
|
|
|
|
.signalSemaphoreValueCount = 1,
|
|
|
|
|
.pWaitSemaphoreValues = wait_values,
|
|
|
|
|
.waitSemaphoreValueCount = 2,
|
|
|
|
|
};
|
|
|
|
|
VkSubmitInfo submit_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
|
|
|
|
.commandBufferCount = 1,
|
|
|
|
|
.pCommandBuffers = &command_buffer,
|
|
|
|
|
.signalSemaphoreCount = 1,
|
|
|
|
|
.pSignalSemaphores = &context->render.frame[i].transfer,
|
|
|
|
|
.waitSemaphoreCount = 2,
|
|
|
|
|
.pWaitSemaphores = wait_semaphores,
|
|
|
|
|
.pWaitDstStageMask = wait_stages,
|
|
|
|
|
.pNext = &timeline_info,
|
|
|
|
|
};
|
|
|
|
|
vkQueueSubmit(context->render.transfer_queue.handle, 1, &submit_info, VK_NULL_HANDLE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|