diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cpp | 15 | ||||
| -rw-r--r-- | src/vk-api.cpp | 55 | ||||
| -rw-r--r-- | src/vk-renderer.cpp | 154 |
3 files changed, 142 insertions, 82 deletions
diff --git a/src/main.cpp b/src/main.cpp index b824fd4..07e799b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include <cassert> #include "thirdparty/renderdoc.h" +#include "imgui.h" #include "vk-renderer.hpp" #include "window.hpp" @@ -65,6 +66,8 @@ int main() { start = std::chrono::high_resolution_clock::now(); + ImGuiIO& io = ImGui::GetIO(); + wnd.poll_events(); for (auto event: wnd.events) { @@ -72,9 +75,13 @@ int main() { case EVENT_TYPES::RESIZE: { width = event.width; height = event.height; + ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->width = width; ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->height = height; + io.DisplaySize.x = (float)width; + io.DisplaySize.y = (float)height; + if (event.width == 0 && event.height == 0) { canRender = false; } else { @@ -129,6 +136,14 @@ int main() { wnd.events.clear(); + + ImGui::NewFrame(); + + ImGui::ShowDemoWindow(); + + ImGui::EndFrame(); + + // To start a frame capture, call StartFrameCapture. // You can specify NULL, NULL for the device to capture on if you have only one device and // either no windows at all or only one window, and it will capture from that device. diff --git a/src/vk-api.cpp b/src/vk-api.cpp index 0c7d114..117f461 100644 --- a/src/vk-api.cpp +++ b/src/vk-api.cpp @@ -65,14 +65,16 @@ Buffer vkapi::create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, V VmaAllocationCreateInfo alloc_create_info = {}; alloc_create_info.usage = mem_usage; alloc_create_info.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; - + VKRESULT(vmaCreateBuffer(context.allocator, &buffer_info, &alloc_create_info, &buffer.handle, &buffer.alloc, &buffer.alloc_info)) + buffer.size = data_size; + return std::move(buffer); } void vkapi::destroy_buffer(Buffer& buffer) { - vmaUnmapMemory(context.allocator, buffer.alloc); + // vmaUnmapMemory(context.allocator, buffer.alloc); vmaDestroyBuffer(context.allocator, buffer.handle, buffer.alloc); } @@ -407,7 +409,7 @@ Pipeline vkapi::create_compute_pipeline(const char* shader_name, std::vector<VkD return std::move(pipeline); } -Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<VkDescriptorSetLayoutBinding>& bindings, VkShaderStageFlagBits shader_stages, VkRenderPass render_pass) { +Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<VkDescriptorSetLayoutBinding>& bindings, VkShaderStageFlagBits shader_stages, VkRenderPass render_pass, std::vector<VkDynamicState> dynamic_states) { Pipeline pipeline; std::vector<VkPipelineShaderStageCreateInfo> stages_create_info = {}; @@ -478,32 +480,36 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<Vk input_assembly_state_create_info.flags = 0; input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - VkViewport viewport = {}; - viewport.x = 0.f; - viewport.y = 0.f; - viewport.width = 384.f; - viewport.height = 186.f; - viewport.minDepth = 0.f; - viewport.maxDepth = 1.f; + // VkViewport viewport = {}; + // viewport.x = 0.f; + // viewport.y = 0.f; + // viewport.width = 384.f; + // viewport.height = 186.f; + // viewport.minDepth = 0.f; + // viewport.maxDepth = 1.f; - VkRect2D scissor = {}; - scissor.offset = { - 0, - 0, - }; - scissor.extent = { - 384, - 186, - }; + // VkRect2D scissor = {}; + // scissor.offset = { + // 0, + // 0, + // }; + // scissor.extent = { + // 384, + // 186, + // }; VkPipelineViewportStateCreateInfo viewport_state_create_info = {}; viewport_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewport_state_create_info.pNext = nullptr; viewport_state_create_info.flags = 0; viewport_state_create_info.viewportCount = 1; - viewport_state_create_info.pViewports = &viewport; + viewport_state_create_info.pViewports = VK_NULL_HANDLE; viewport_state_create_info.scissorCount = 1; - viewport_state_create_info.pScissors = &scissor; + viewport_state_create_info.pScissors = VK_NULL_HANDLE; + // viewport_state_create_info.viewportCount = 1; + // viewport_state_create_info.pViewports = &viewport; + // viewport_state_create_info.scissorCount = 1; + // viewport_state_create_info.pScissors = &scissor; VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = {}; rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; @@ -543,6 +549,12 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<Vk color_blend_state_create_info.attachmentCount = 1; color_blend_state_create_info.pAttachments = &color_attachment_state; + VkPipelineDynamicStateCreateInfo dynamic_state_create_info = {}; + dynamic_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamic_state_create_info.pNext = VK_NULL_HANDLE; + dynamic_state_create_info.flags = 0; + dynamic_state_create_info.dynamicStateCount = dynamic_states.size(); + dynamic_state_create_info.pDynamicStates = dynamic_states.data(); VkGraphicsPipelineCreateInfo pipeline_create_info = {}; pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; @@ -556,6 +568,7 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<Vk pipeline_create_info.pRasterizationState = &rasterization_state_create_info; pipeline_create_info.pMultisampleState = &multisample_state_create_info; pipeline_create_info.pColorBlendState = &color_blend_state_create_info; + pipeline_create_info.pDynamicState = &dynamic_state_create_info; pipeline_create_info.layout = pipeline.layout; pipeline_create_info.renderPass = render_pass; pipeline_create_info.subpass = 0; diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp index f87871a..9636465 100644 --- a/src/vk-renderer.cpp +++ b/src/vk-renderer.cpp @@ -21,6 +21,11 @@ struct VkVertex { uint32_t padding[3]; }; +struct UiTransforms { + float scale_x, scale_y; + float translate_x, translate_y; +}; + vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { platform_surface = api.create_surface(wnd); swapchain = api.create_swapchain( @@ -95,13 +100,25 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { }, { .binding = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + .pImmutableSamplers = VK_NULL_HANDLE, + }, + { + .binding = 2, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, .pImmutableSamplers = VK_NULL_HANDLE, }, }; - ui_pipeline = api.create_graphics_pipeline("ui", ui_sets_bindings, (VkShaderStageFlagBits)(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT), render_pass); + + std::vector<VkDynamicState> dynamic_states { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR + }; + ui_pipeline = api.create_graphics_pipeline("ui", ui_sets_bindings, (VkShaderStageFlagBits)(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT), render_pass, dynamic_states); ui_sets = api.create_descriptor_sets(ui_pipeline.descriptor_set_layout, swapchain.image_count); ImGui::CreateContext(); @@ -152,6 +169,11 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { api.submit(cmd_buf, VK_NULL_HANDLE, VK_NULL_HANDLE, submission_fences[frame_index]); + // VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[frame_index], VK_TRUE, UINT64_MAX)) + // VKRESULT(vkResetFences(api.context.device, 1, &submission_fences[frame_index])) + + // api.destroy_buffer(staging_buffer); + frame_index++; VkSamplerCreateInfo sampler_create_info = {}; @@ -177,11 +199,16 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { VKRESULT(vkCreateSampler(api.context.device, &sampler_create_info, VK_NULL_HANDLE, &sampler)) for (size_t index = 0; index < swapchain.image_count; index++) { - api.update_descriptor_set_image(ui_sets[index], ui_sets_bindings[1], ui_texture.view, sampler); + api.update_descriptor_set_image(ui_sets[index], ui_sets_bindings[2], ui_texture.view, sampler); } ui_vertex_buffers.resize(swapchain.image_count); ui_index_buffers.resize(swapchain.image_count); + + for (size_t index = 0; index < swapchain.image_count; index++) { + ui_transforms_buffers.push_back(api.create_buffer(sizeof(UiTransforms), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU)); + api.update_descriptor_set_buffer(ui_sets[index], ui_sets_bindings[1], ui_transforms_buffers[index]); + } } vkrenderer::~vkrenderer() { @@ -203,16 +230,16 @@ vkrenderer::~vkrenderer() { api.destroy_framebuffer(framebuffer); } - for (auto& v_buffer_array: ui_vertex_buffers) { - for (auto& vertex_buffer: v_buffer_array) { - api.destroy_buffer(vertex_buffer); - } + for (auto& transforms_buffer: ui_transforms_buffers) { + api.destroy_buffer(transforms_buffer); } - for (auto& i_buffer_array: ui_index_buffers) { - for (auto& index_buffer: i_buffer_array) { - api.destroy_buffer(index_buffer); - } + for (auto& vertex_buffer: ui_vertex_buffers) { + api.destroy_buffer(vertex_buffer); + } + + for (auto& index_buffer: ui_index_buffers) { + api.destroy_buffer(index_buffer); } api.destroy_command_buffers(command_buffers); @@ -224,68 +251,49 @@ vkrenderer::~vkrenderer() { } void vkrenderer::begin_frame() { - - ImGuiIO& io = ImGui::GetIO(); - io.DisplaySize.x = (float)swapchain.extent.width; - io.DisplaySize.y = (float)swapchain.extent.height; - io.DisplayFramebufferScale = { 1.f, 1.f }; - - ImGui::NewFrame(); - - ImGui::Text("Hello, world!"); - - ImGui::EndFrame(); - ImGui::Render(); ImDrawData* draw_data = ImGui::GetDrawData(); - if (ui_vertex_buffers[frame_index].size() == 0) { - std::vector<Buffer> temp_vertex_buffers {}; - std::vector<Buffer> temp_index_buffers {}; + // Update descriptor with only the part of the buffer we are interested in + if (ui_vertex_buffers[frame_index].size < draw_data->TotalVtxCount * sizeof(VkVertex)) { + api.destroy_buffer(ui_vertex_buffers[frame_index]); - // Update descriptor with only the part of the buffer we are interested in - for (size_t cmd_index = 0; cmd_index < draw_data->CmdListsCount; cmd_index++) { - ImDrawList* draw_list = draw_data->CmdLists[cmd_index]; - auto vbuf = draw_list->VtxBuffer; - auto ibuf = draw_list->IdxBuffer; - - std::vector<VkVertex> vertices; + ui_vertex_buffers[frame_index] = api.create_buffer(draw_data->TotalVtxCount * sizeof(VkVertex), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); + api.update_descriptor_set_buffer(ui_sets[frame_index], ui_sets_bindings[0], ui_vertex_buffers[frame_index]); + } + if (ui_index_buffers[frame_index].size < draw_data->TotalIdxCount * sizeof(ImDrawIdx)) { + api.destroy_buffer(ui_index_buffers[frame_index]); - for (auto& imVertex: vbuf) { - vertices.push_back(*((VkVertex*)&imVertex)); - } + ui_index_buffers[frame_index] = api.create_buffer(draw_data->TotalIdxCount * sizeof(ImDrawIdx), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); + } - auto vk_vtx_buf = api.create_buffer(vertices.size() * sizeof(VkVertex), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); - std::memcpy(vk_vtx_buf.alloc_info.pMappedData, vertices.data(), vertices.size() * sizeof(VkVertex)); + ((UiTransforms*)ui_transforms_buffers[frame_index].alloc_info.pMappedData)->scale_x = 2.f / draw_data->DisplaySize.x; + ((UiTransforms*)ui_transforms_buffers[frame_index].alloc_info.pMappedData)->scale_y = 2.f / draw_data->DisplaySize.y; + ((UiTransforms*)ui_transforms_buffers[frame_index].alloc_info.pMappedData)->translate_x = -1.f - draw_data->DisplayPos.x * (2.f / draw_data->DisplaySize.x); + ((UiTransforms*)ui_transforms_buffers[frame_index].alloc_info.pMappedData)->translate_y = -1.f - draw_data->DisplayPos.y * (2.f / draw_data->DisplaySize.y); - auto vk_idx_buf = api.create_buffer(ibuf.Size * sizeof(ImDrawIdx), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); - std::memcpy(vk_idx_buf.alloc_info.pMappedData, ibuf.Data, ibuf.Size * sizeof(ImDrawIdx)); + off_t vertex_buffer_offset = 0; + off_t index_buffer_offset = 0; + for (uint32_t draw_list_index = 0; draw_list_index < draw_data->CmdListsCount; draw_list_index++) { + auto vertex_buffer = draw_data->CmdLists[draw_list_index]->VtxBuffer; + auto index_buffer = draw_data->CmdLists[draw_list_index]->IdxBuffer; + std::vector<VkVertex> vertices; - ui_vertex_buffers[frame_index].push_back(vk_vtx_buf); - ui_index_buffers[frame_index].push_back(vk_idx_buf); - // temp_vertex_buffers.push_back(vk_vtx_buf); - // temp_index_buffers.push_back(vk_idx_buf); + for (auto& imVertex: vertex_buffer) { + vertices.push_back(*((VkVertex*)&imVertex)); } + + std::memcpy((void*) ((uint64_t)ui_vertex_buffers[frame_index].alloc_info.pMappedData + (vertex_buffer_offset * sizeof(VkVertex))), vertices.data(), vertex_buffer.Size * sizeof(VkVertex)); + std::memcpy((void*) ((uint64_t)ui_index_buffers[frame_index].alloc_info.pMappedData + (index_buffer_offset * sizeof(ImDrawIdx))), index_buffer.Data, index_buffer.Size * sizeof(ImDrawIdx)); + + vertex_buffer_offset += vertex_buffer.Size; + index_buffer_offset += index_buffer.Size; } VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[frame_index], VK_TRUE, UINT64_MAX)) VKRESULT(vkResetFences(api.context.device, 1, &submission_fences[frame_index])) - // for (auto& vertex_buffer: ui_vertex_buffers[frame_index]) { - // api.destroy_buffer(vertex_buffer); - // } - - // for (auto& index_buffer: ui_index_buffers[frame_index]) { - // api.destroy_buffer(index_buffer); - // } - - // ui_vertex_buffers[frame_index].clear(); - // ui_index_buffers[frame_index].clear(); - - // ui_vertex_buffers[frame_index] = std::move(temp_vertex_buffers); - // ui_index_buffers[frame_index] = std::move(temp_index_buffers); - 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); @@ -336,17 +344,41 @@ void vkrenderer::ui() { vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_pipeline.handle); + VkViewport viewport = {}; + viewport.x = draw_data->DisplayPos.x; + viewport.y = draw_data->DisplayPos.y; + viewport.width = draw_data->DisplaySize.x; + viewport.height = draw_data->DisplaySize.y; + viewport.minDepth = 0.f; + viewport.maxDepth = 1.f; + + vkCmdSetViewport(cmd_buf, 0, 1, &viewport); + + off_t vertex_buffer_offset = 0; + off_t index_buffer_offset = 0; 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(ui_sets[frame_index], ui_sets_bindings[0], ui_vertex_buffers[frame_index][cmd_index]); - - vkCmdBindIndexBuffer(cmd_buf, ui_index_buffers[frame_index][cmd_index].handle, 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(cmd_buf, ui_index_buffers[frame_index].handle, 0, VK_INDEX_TYPE_UINT16); vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_pipeline.layout, 0, 1, &ui_sets[frame_index], 0, VK_NULL_HANDLE); for (auto& draw_cmd: draw_list->CmdBuffer) { - vkCmdDrawIndexed(cmd_buf, draw_cmd.ElemCount, 1, draw_cmd.IdxOffset, draw_cmd.VtxOffset, 0); + VkRect2D rect = {}; + rect.offset = { + (int32_t)draw_cmd.ClipRect.x, + (int32_t)draw_cmd.ClipRect.y + }; + rect.extent = { + (uint32_t)draw_cmd.ClipRect.z, + (uint32_t)draw_cmd.ClipRect.w, + }; + vkCmdSetScissor(cmd_buf, 0, 1, &rect); + + vkCmdDrawIndexed(cmd_buf, draw_cmd.ElemCount, 1, index_buffer_offset + draw_cmd.IdxOffset, vertex_buffer_offset + draw_cmd.VtxOffset, 0); } + + vertex_buffer_offset += draw_list->VtxBuffer.Size; + index_buffer_offset += draw_list->IdxBuffer.Size; } vkCmdEndRenderPass(cmd_buf); |
