From 45783d96ec6f84893c85789ff5e5e2243e7f3db9 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Fri, 19 Feb 2021 23:23:41 +0100 Subject: Attempt at rendering imgui content --- src/main.cpp | 5 +++ src/vk-api.cpp | 100 +++++++++++++++++++++++++++++++-------------- src/vk-renderer.cpp | 114 +++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 179 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 9736aaf..120f8ed 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -139,12 +139,17 @@ int main() { if(rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL); if (canRender) { + renderer.begin_frame(); + // renderer.ui(); + if (((input_data*) renderer.compute_shader_buffer.mapped_ptr)->sample_index < samples_per_pixel) { bool clear = ((input_data*) renderer.compute_shader_buffer.mapped_ptr)->sample_index == 0; renderer.compute(width, height, clear); ((input_data*) renderer.compute_shader_buffer.mapped_ptr)->sample_index++; } + + renderer.finish_frame(); } // stop the capture diff --git a/src/vk-api.cpp b/src/vk-api.cpp index b6070e5..eb5411a 100644 --- a/src/vk-api.cpp +++ b/src/vk-api.cpp @@ -230,10 +230,12 @@ void vkapi::destroy_command_buffers(std::vector &command_buffer // TODO: attachment structure -VkRenderPass vkapi::create_render_pass(std::vector& attachments_format) { - std::vector attachments_description = {}; +VkRenderPass vkapi::create_render_pass(std::vector& color_attachments_format) { + std::vector attachments_description = {}; + std::vector attachments_reference = {}; - for (auto& format: attachments_format) { + for (size_t attachment_index = 0; attachment_index < color_attachments_format.size(); attachment_index++) { + auto format = color_attachments_format[attachment_index]; VkAttachmentDescription attachment_description = {}; attachment_description.flags = 0; attachment_description.format = format; @@ -244,36 +246,30 @@ VkRenderPass vkapi::create_render_pass(std::vector& attachments_format attachment_description.finalLayout = VK_IMAGE_LAYOUT_GENERAL; attachments_description.push_back(attachment_description); - } - std::vector subpasses_description = {}; - VkSubpassDescription subpass_description = {}; - subpass_description.flags = 0; - subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass_description.inputAttachmentCount = 0; - subpass_description.pInputAttachments = 0; - subpass_description.colorAttachmentCount = 0; - subpass_description.pColorAttachments = 0; - subpass_description.pResolveAttachments = VK_NULL_HANDLE; - subpass_description.pDepthStencilAttachment = VK_NULL_HANDLE; - subpass_description.preserveAttachmentCount = 0; - subpass_description.pPreserveAttachments = VK_NULL_HANDLE; + VkAttachmentReference attachment_reference = {}; + attachment_reference.attachment = attachment_index; + attachment_reference.layout = VK_IMAGE_LAYOUT_GENERAL; - subpasses_description.push_back(subpass_description); + attachments_reference.push_back(attachment_reference); + } - std::vector subpasses_dependency = {}; + VkSubpassDescription subpass_description = {}; + subpass_description.flags = 0; + subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass_description.colorAttachmentCount = attachments_reference.size(); + subpass_description.pColorAttachments = attachments_reference.data(); + subpass_description.pDepthStencilAttachment = VK_NULL_HANDLE; VkRenderPass render_pass; - VkRenderPassCreateInfo create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - create_info.pNext = VK_NULL_HANDLE; - create_info.flags = 0; - create_info.attachmentCount = attachments_description.size(); - create_info.pAttachments = attachments_description.data(); - create_info.subpassCount = subpasses_description.size(); - create_info.pSubpasses = subpasses_description.data(); - create_info.dependencyCount = subpasses_dependency.size(); - create_info.pDependencies = subpasses_dependency.data(); + VkRenderPassCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + create_info.pNext = VK_NULL_HANDLE; + create_info.flags = 0; + create_info.attachmentCount = attachments_description.size(); + create_info.pAttachments = attachments_description.data(); + create_info.subpassCount = 1; + create_info.pSubpasses = &subpass_description; VKRESULT(vkCreateRenderPass(context.device, &create_info, VK_NULL_HANDLE, &render_pass)) @@ -285,6 +281,50 @@ void vkapi::destroy_renderpass(VkRenderPass render_pass) { } +VkFramebuffer vkapi::create_framebuffer(VkRenderPass render_pass, std::vector& images, VkExtent2D size) { + VkFramebuffer framebuffer; + std::vector attachements; + for (auto& image: images) { + attachements.push_back(image.view); + } + + VkFramebufferCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + create_info.pNext = VK_NULL_HANDLE; + create_info.flags = 0; + create_info.renderPass = render_pass; + create_info.attachmentCount = attachements.size(); + create_info.pAttachments = attachements.data(); + create_info.width = size.width; + create_info.height = size.height; + create_info.layers = 1; + + VKRESULT(vkCreateFramebuffer(context.device, &create_info, VK_NULL_HANDLE, &framebuffer)) + + return framebuffer; +} + +std::vector vkapi::create_framebuffers(VkRenderPass render_pass, std::vector& images, VkExtent2D size, uint32_t framebuffer_count) { + std::vector framebuffers { framebuffer_count }; + + for (auto& framebuffer: framebuffers) { + framebuffer = create_framebuffer(render_pass, images, size); + } + + return std::move(framebuffers); +} + +void vkapi::destroy_framebuffer(VkFramebuffer framebuffer) { + vkDestroyFramebuffer(context.device, framebuffer, VK_NULL_HANDLE); +} + +void vkapi::destroy_framebuffers(std::vector& framebuffers) { + for (auto& framebuffer: framebuffers) { + vkDestroyFramebuffer(context.device, framebuffer, VK_NULL_HANDLE); + } +} + + Pipeline vkapi::create_compute_pipeline(const char* shader_name, std::vector bindings) { Pipeline pipeline; @@ -355,7 +395,7 @@ Pipeline vkapi::create_compute_pipeline(const char* shader_name, std::vector bindings, VkRenderPass render_pass, uint32_t subpass) { +Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector bindings, VkShaderStageFlagBits shader_stages, VkRenderPass render_pass) { Pipeline pipeline; std::vector stages_create_info = {}; @@ -497,7 +537,7 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, VkShaderStageF pipeline_create_info.pColorBlendState = &color_blend_state_create_info; pipeline_create_info.layout = pipeline.layout; pipeline_create_info.renderPass = render_pass; - pipeline_create_info.subpass = subpass; + pipeline_create_info.subpass = 0; VKRESULT(vkCreateGraphicsPipelines(context.device, VK_NULL_HANDLE, 1, &pipeline_create_info, VK_NULL_HANDLE, &pipeline.handle)) diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp index cffdaf2..21918cb 100644 --- a/src/vk-renderer.cpp +++ b/src/vk-renderer.cpp @@ -46,7 +46,7 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { } }; - compute_pipeline = api.create_compute_pipeline("./shaders/compute", bindings); + compute_pipeline = api.create_compute_pipeline("compute", bindings); command_buffers = api.create_command_buffers(swapchain.image_count); @@ -63,6 +63,26 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { execution_semaphores = api.create_semaphores(swapchain.image_count); acquire_semaphores = api.create_semaphores(swapchain.image_count); + // std::vector attachments_format { swapchain.surface_format.format }; + // render_pass = api.create_render_pass(attachments_format); + + // std::vector ui_pipeline_bindings { + // { + // .binding = 0, + // .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + // .descriptorCount = 1, + // .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + // .pImmutableSamplers = VK_NULL_HANDLE, + // }, + // }; + // ui_pipeline = api.create_graphics_pipeline("ui", ui_pipeline_bindings, (VkShaderStageFlagBits)(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT), render_pass); + // ui_sets = api.create_descriptor_sets(ui_pipeline.descriptor_set_layout, swapchain.image_count); + + // for (auto& image : swapchain.images) { + // std::vector attachments { image }; + // framebuffers.push_back(api.create_framebuffer(render_pass, attachments, swapchain.extent)); + // } + compute_shader_buffer = api.create_buffer(sizeof(inputs), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); std::memcpy(compute_shader_buffer.mapped_ptr, &inputs, sizeof(inputs)); @@ -89,20 +109,16 @@ vkrenderer::~vkrenderer() { api.destroy_surface(platform_surface); } -void vkrenderer::ui() { - ImGui::NewFrame(); - ImGui::Render(); - ImDrawData* draw_data = ImGui::GetDrawData(); -} - -void vkrenderer::compute(uint32_t width, uint32_t height, bool clear) { +void vkrenderer::begin_frame() { VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[frame_index], VK_TRUE, UINT64_MAX)) VKRESULT(vkResetFences(api.context.device, 1, &submission_fences[frame_index])) - uint32_t swapchain_image_index = 0; + swapchain_image_index = 0; auto acquire_result = vkAcquireNextImageKHR(api.context.device, swapchain.handle, UINT64_MAX, acquire_semaphores[frame_index], VK_NULL_HANDLE, &swapchain_image_index); handle_swapchain_result(acquire_result); + auto cmd_buf = command_buffers[frame_index]; + auto output_image = accumulation_images[0]; auto accumulation_image = accumulation_images[1]; @@ -124,9 +140,83 @@ void vkrenderer::compute(uint32_t width, uint32_t height, bool clear) { api.update_descriptor_set_image(compute_shader_sets[swapchain_image_index], images[0], output_image.view); api.update_descriptor_set_image(compute_shader_sets[swapchain_image_index], images[1], accumulation_image.view); + api.start_record(cmd_buf); + +} + +void vkrenderer::ui() { + ImGui::NewFrame(); + ImGui::Render(); + ImDrawData* draw_data = ImGui::GetDrawData(); + + for (size_t cmd_index = 0; cmd_index < draw_data->CmdListsCount; cmd_index++) { + ImDrawList* draw_list = draw_data->CmdLists[cmd_index]; + ImVector vertex_buffer = draw_list->VtxBuffer; + ImVector index_buffer = draw_list->IdxBuffer; + + auto vk_vtx_buf = api.create_buffer(vertex_buffer.Size * sizeof(vertex_buffer.Data[0]), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); + std::memcpy(vk_vtx_buf.mapped_ptr, vertex_buffer.Data, vertex_buffer.Size * sizeof(vertex_buffer.Data[0])); + + auto vk_idx_buf = api.create_buffer(index_buffer.Size * sizeof(index_buffer.Data[0]), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); + std::memcpy(vk_idx_buf.mapped_ptr, index_buffer.Data, index_buffer.Size * sizeof(index_buffer.Data[0])); + + ui_vertex_buffers.push_back(vk_vtx_buf); + ui_index_buffers.push_back(vk_idx_buf); + } + auto cmd_buf = command_buffers[frame_index]; - api.start_record(cmd_buf); + VkRect2D render_area = { + { + 0, + 0, + }, + swapchain.extent + }; + VkClearValue clear_value = { 0.f, 0.f, 0.f, 1.f }; + VkRenderPassBeginInfo render_pass_begin_info = {}; + render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + render_pass_begin_info.pNext = VK_NULL_HANDLE; + render_pass_begin_info.renderPass = render_pass; + render_pass_begin_info.framebuffer = framebuffers[swapchain_image_index]; + render_pass_begin_info.renderArea = render_area; + render_pass_begin_info.clearValueCount = 1; + render_pass_begin_info.pClearValues = &clear_value; + + vkCmdBeginRenderPass(cmd_buf, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE); + + vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_pipeline.layout, 0, 1, &ui_sets[frame_index], 0, nullptr); + + vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_pipeline.handle); + + VkDescriptorSetLayoutBinding binding = { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + .pImmutableSamplers = VK_NULL_HANDLE, + }; + + for (size_t cmd_index = 0; cmd_index < draw_data->CmdListsCount; cmd_index++) { + ImDrawList* draw_list = draw_data->CmdLists[cmd_index]; + + api.update_descriptor_set_buffer(compute_shader_sets[frame_index], binding, ui_vertex_buffers[cmd_index]); + + vkCmdBindIndexBuffer(cmd_buf, ui_index_buffers[cmd_index].handle, 0, VK_INDEX_TYPE_UINT16); + + for (auto& draw_cmd: draw_list->CmdBuffer) { + vkCmdDrawIndexed(cmd_buf, draw_cmd.ElemCount, 1, draw_cmd.IdxOffset, draw_cmd.VtxOffset, 0); + } + } + + vkCmdEndRenderPass(cmd_buf); +} + +void vkrenderer::compute(uint32_t width, uint32_t height, bool clear) { + auto cmd_buf = command_buffers[frame_index]; + + auto output_image = accumulation_images[0]; + auto accumulation_image = accumulation_images[1]; if (clear) { api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT, accumulation_image); @@ -151,6 +241,10 @@ void vkrenderer::compute(uint32_t width, uint32_t height, bool clear) { api.blit_full(cmd_buf, output_image, swapchain.images[swapchain_image_index]); api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, swapchain.images[swapchain_image_index]); +} + +void vkrenderer::finish_frame() { + auto cmd_buf = command_buffers[frame_index]; api.end_record(cmd_buf); -- cgit v1.3