diff --git a/.vims b/.vims index ca71366..89ee277 100644 --- a/.vims +++ b/.vims @@ -13,12 +13,39 @@ if &shortmess =~ 'A' else set shortmess=aoO endif -badd +1 src/graphics/pipeline.cpp +badd +38 ~/programming/3D-CG-CV/Week3/index.js +badd +99 src/inferno.cpp +badd +47 src/graphics/vkrenderer.cpp +badd +92 src/gui/gui.hpp +badd +38 src/renderer/renderer.hpp +badd +45 src/graphics/vkrenderer.hpp argglobal %argdel -edit src/graphics/pipeline.cpp +edit src/gui/gui.hpp +let s:save_splitbelow = &splitbelow +let s:save_splitright = &splitright +set splitbelow splitright +wincmd _ | wincmd | +vsplit +wincmd _ | wincmd | +vsplit +2wincmd h +wincmd w +wincmd w +let &splitbelow = s:save_splitbelow +let &splitright = s:save_splitright +wincmd t +let s:save_winminheight = &winminheight +let s:save_winminwidth = &winminwidth +set winminheight=0 +set winheight=1 +set winminwidth=0 +set winwidth=1 +exe 'vert 1resize ' . ((&columns * 111 + 181) / 362) +exe 'vert 2resize ' . ((&columns * 124 + 181) / 362) +exe 'vert 3resize ' . ((&columns * 125 + 181) / 362) argglobal -balt src/graphics/pipeline.cpp +balt src/inferno.cpp setlocal fdm=manual setlocal fde=0 setlocal fmr={{{,}}} @@ -29,12 +56,63 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 1 - ((0 * winheight(0) + 27) / 54) +let s:l = 58 - ((57 * winheight(0) + 35) / 71) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 1 +keepjumps 58 normal! 0 +wincmd w +argglobal +if bufexists(fnamemodify("src/graphics/vkrenderer.cpp", ":p")) | buffer src/graphics/vkrenderer.cpp | else | edit src/graphics/vkrenderer.cpp | endif +if &buftype ==# 'terminal' + silent file src/graphics/vkrenderer.cpp +endif +balt src/renderer/renderer.hpp +setlocal fdm=manual +setlocal fde=0 +setlocal fmr={{{,}}} +setlocal fdi=# +setlocal fdl=0 +setlocal fml=1 +setlocal fdn=20 +setlocal fen +silent! normal! zE +let &fdl = &fdl +let s:l = 48 - ((47 * winheight(0) + 35) / 71) +if s:l < 1 | let s:l = 1 | endif +keepjumps exe s:l +normal! zt +keepjumps 48 +normal! 036| +wincmd w +argglobal +if bufexists(fnamemodify("src/graphics/vkrenderer.hpp", ":p")) | buffer src/graphics/vkrenderer.hpp | else | edit src/graphics/vkrenderer.hpp | endif +if &buftype ==# 'terminal' + silent file src/graphics/vkrenderer.hpp +endif +balt src/renderer/renderer.hpp +setlocal fdm=manual +setlocal fde=0 +setlocal fmr={{{,}}} +setlocal fdi=# +setlocal fdl=0 +setlocal fml=1 +setlocal fdn=20 +setlocal fen +silent! normal! zE +let &fdl = &fdl +let s:l = 45 - ((44 * winheight(0) + 35) / 71) +if s:l < 1 | let s:l = 1 | endif +keepjumps exe s:l +normal! zt +keepjumps 45 +normal! 0 +wincmd w +3wincmd w +exe 'vert 1resize ' . ((&columns * 111 + 181) / 362) +exe 'vert 2resize ' . ((&columns * 124 + 181) / 362) +exe 'vert 3resize ' . ((&columns * 125 + 181) / 362) tabnext 1 if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal' silent exe 'bwipe ' . s:wipebuf @@ -42,6 +120,8 @@ endif unlet! s:wipebuf set winheight=1 winwidth=20 let &shortmess = s:shortmess_save +let &winminheight = s:save_winminheight +let &winminwidth = s:save_winminwidth let s:sx = expand(":p:r")."x.vim" if filereadable(s:sx) exe "source " . fnameescape(s:sx) diff --git a/src/graphics/vkrenderer.cpp b/src/graphics/vkrenderer.cpp index 9b67f62..263f358 100644 --- a/src/graphics/vkrenderer.cpp +++ b/src/graphics/vkrenderer.cpp @@ -5,7 +5,10 @@ #include "pipeline.hpp" #include "swapchain.hpp" +#include "gui/gui.hpp" + #include "yolo/yolo.hpp" +#include #include namespace inferno::graphics { @@ -46,6 +49,8 @@ VulkanRenderer* renderer_create(GraphicsDevice* device) renderer->CurrentFrameIndex = 0; renderer->CurrentFrame = &renderer->InFlight[0]; + gui::imgui_init(renderer); + return renderer; } @@ -63,7 +68,7 @@ void renderer_cleanup(VulkanRenderer* renderer) } } -void renderer_configure_command_buffer(Renderer* renderer) +void renderer_configure_command_buffer(VulkanRenderer* renderer) { renderer->CommandBuffersInFlight.resize(FRAMES_IN_FLIGHT); VkCommandBufferAllocateInfo allocInfo {}; @@ -81,7 +86,7 @@ void renderer_configure_command_buffer(Renderer* renderer) yolo::debug("Command buffer created"); } -void renderer_record_command_buffer(Renderer* renderer, uint32_t imageIndex) +void renderer_record_command_buffer(VulkanRenderer* renderer, uint32_t imageIndex) { VkCommandBufferBeginInfo beginInfo {}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -94,6 +99,9 @@ void renderer_record_command_buffer(Renderer* renderer, uint32_t imageIndex) yolo::error("failed to begin recording command buffer!"); } + renderer->CommandBufferInFlight + = &renderer->CommandBuffersInFlight[renderer->CurrentFrameIndex]; + VkImageMemoryBarrier imageMemoryBarrier {}; imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; @@ -107,9 +115,8 @@ void renderer_record_command_buffer(Renderer* renderer, uint32_t imageIndex) imageMemoryBarrier.subresourceRange.levelCount = 1; vkCmdPipelineBarrier(renderer->CommandBuffersInFlight[renderer->CurrentFrameIndex], - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, - &imageMemoryBarrier); + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); VkClearValue clearColor = { { { 0.0f, 0.0f, 0.0f, 1.0f } } }; VkRenderingAttachmentInfo attachmentInfo {}; @@ -145,6 +152,70 @@ void renderer_record_command_buffer(Renderer* renderer, uint32_t imageIndex) renderer->CommandBuffersInFlight[renderer->CurrentFrameIndex], &renderingInfo); } +void renderer_submit_oneoff(VulkanRenderer* renderer, + std::function callback, bool post) +{ + if (post) { + renderer->SubmitQueueOneOffPostFrame.push_back(callback); + } else { + renderer->SubmitQueueOneOffPreFrame.push_back(callback); + } +} + +void renderer_submit_repeat(VulkanRenderer* renderer, + std::function callback, bool post) +{ + if (post) { + renderer->SubmitQueuePostFrame.push_back(callback); + } else { + renderer->SubmitQueuePreFrame.push_back(callback); + } +} + +void work_queue(VulkanRenderer* renderer, + std::vector>* queue, + bool clear) +{ + for (auto& callback : *queue) { + callback(renderer, renderer->CommandBufferInFlight); + } + if (clear) { + queue->clear(); + } +} + +void renderer_submit_now(VulkanRenderer* renderer, + std::function callback) +{ + VkCommandBufferAllocateInfo allocInfo {}; + allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocInfo.commandPool = renderer->Device->VulkanCommandPool; + allocInfo.commandBufferCount = 1; + + VkCommandBuffer commandBuffer; + vkAllocateCommandBuffers(renderer->Device->VulkanDevice, &allocInfo, &commandBuffer); + + VkCommandBufferBeginInfo beginInfo {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + vkBeginCommandBuffer(commandBuffer, &beginInfo); + + callback(renderer, &commandBuffer); + + vkEndCommandBuffer(commandBuffer); + VkSubmitInfo submitInfo {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &commandBuffer; + + vkQueueSubmit(renderer->Device->VulkanGraphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); + vkQueueWaitIdle(renderer->Device->VulkanGraphicsQueue); + + vkFreeCommandBuffers(renderer->Device->VulkanDevice, renderer->Device->VulkanCommandPool, 1, &commandBuffer); +} + bool renderer_begin_frame(VulkanRenderer* renderer) { vkWaitForFences(renderer->Device->VulkanDevice, 1, &renderer->CurrentFrame->Fence, @@ -166,12 +237,30 @@ bool renderer_begin_frame(VulkanRenderer* renderer) vkResetCommandBuffer( renderer->CommandBuffersInFlight[renderer->CurrentFrameIndex], 0); renderer_record_command_buffer(renderer, renderer->ImageIndex); + + work_queue(renderer, &renderer->SubmitQueueOneOffPreFrame, true); + work_queue(renderer, &renderer->SubmitQueuePreFrame, false); + + gui::imgui_new_frame(); + + ImGui::Begin("main", nullptr, WINDOW_FLAGS); + // ImGui::SetWindowPos(Im) + return true; } -bool renderer_draw_frame(Renderer* renderer) +bool renderer_draw_frame(VulkanRenderer* renderer) { - vkCmdEndRendering(renderer->CommandBuffersInFlight[renderer->CurrentFrameIndex]); + work_queue(renderer, &renderer->SubmitQueueOneOffPreFrame, true); + work_queue(renderer, &renderer->SubmitQueuePreFrame, false); + + ImGui::End(); + ImGui::Render(); + auto io = ImGui::GetIO(); + ImGui_ImplVulkan_RenderDrawData( + ImGui::GetDrawData(), *renderer->CommandBufferInFlight); + + vkCmdEndRendering(*renderer->CommandBufferInFlight); VkImageMemoryBarrier imageMemoryBarrier {}; imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; diff --git a/src/graphics/vkrenderer.hpp b/src/graphics/vkrenderer.hpp index 31596d3..258d51e 100644 --- a/src/graphics/vkrenderer.hpp +++ b/src/graphics/vkrenderer.hpp @@ -2,6 +2,9 @@ #include "graphics.hpp" +#include +#include + namespace inferno::graphics { struct GraphicsDevice; @@ -11,7 +14,6 @@ struct RenderPass; struct GenBuffer; struct Shader; - // TODO: Make the inflight frames work better typedef struct FrameInFlight { VkSemaphore ImageAvailable; @@ -29,20 +31,38 @@ typedef struct VulkanRenderer { // not do this? CommandBuffers need to be *sequential* // in client memory std::vector CommandBuffersInFlight; - std::vector InFlight; + VkCommandBuffer* CommandBufferInFlight; + std::vector InFlight; FrameInFlight* CurrentFrame; + uint32_t CurrentFrameIndex; uint32_t ImageIndex; -} Renderer; -Renderer* renderer_create(GraphicsDevice* device); -void renderer_cleanup(Renderer* renderer); + std::vector> + SubmitQueueOneOffPreFrame; + std::vector> + SubmitQueueOneOffPostFrame; + std::vector> + SubmitQueuePreFrame; + std::vector> + SubmitQueuePostFrame; +} VulkanRenderer; -void renderer_configure_command_buffer(Renderer* renderer); +VulkanRenderer* renderer_create(GraphicsDevice* device); +void renderer_cleanup(VulkanRenderer* renderer); -bool renderer_begin_frame(Renderer* renderer); -bool renderer_draw_frame(Renderer* renderer); +void renderer_configure_command_buffer(VulkanRenderer* renderer); + +void renderer_submit_oneoff(VulkanRenderer* renderer, + std::function callback, bool post = false); +void renderer_submit_repeat(VulkanRenderer* renderer, + std::function callback, bool post = false); +void renderer_submit_now(VulkanRenderer* renderer, + std::function callback); + + +bool renderer_begin_frame(VulkanRenderer* renderer); +bool renderer_draw_frame(VulkanRenderer* renderer); } - diff --git a/src/gui/gui.hpp b/src/gui/gui.hpp index 156ade0..ca455cb 100644 --- a/src/gui/gui.hpp +++ b/src/gui/gui.hpp @@ -3,16 +3,18 @@ #include "graphics.hpp" #include "graphics/device.hpp" +#include "graphics/vkrenderer.hpp" + #include "window.hpp" #include "yolo/yolo.hpp" namespace inferno::gui { -inline void imgui_init(graphics::GraphicsDevice* device) +inline void imgui_init(graphics::VulkanRenderer* renderer) { - VkDescriptorPoolSize pool_sizes[] = { - { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, + graphics::GraphicsDevice* device = renderer->Device; + VkDescriptorPoolSize pool_sizes[] = { { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, @@ -22,8 +24,7 @@ inline void imgui_init(graphics::GraphicsDevice* device) { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, - { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } - }; + { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } }; VkDescriptorPoolCreateInfo pool_info = {}; pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; @@ -54,20 +55,34 @@ inline void imgui_init(graphics::GraphicsDevice* device) ImGui_ImplVulkan_Init(&init_info, VK_NULL_HANDLE); // execute a gpu command to upload imgui font textures - // immediate_submit([&](VkCommandBuffer cmd) { - // ImGui_ImplVulkan_CreateFontsTexture(cmd); - // }); - - // clear font textures from cpu data - // ImGui_ImplVulkan_DestroyFontUploadObjects(); - - // add the destroy the imgui created structures - // _mainDeletionQueue.push_function([=]() { - // vkDestroyDescriptorPool(_device, imguiPool, nullptr); - // ImGui_ImplVulkan_Shutdown(); - // }); + graphics::renderer_submit_now( + renderer, [](graphics::VulkanRenderer* renderer, VkCommandBuffer* cmd) { + ImGui_ImplVulkan_CreateFontsTexture(*cmd); + yolo::debug("Submit ImGui fonts"); + }); yolo::info("Initialized ImGUI"); } +inline void imgui_new_frame() +{ + ImGui_ImplVulkan_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); +} + +inline void imgui_render_frame(VkCommandBuffer command_buffer) +{ + ImGui::Render(); + ImDrawData* draw_data = ImGui::GetDrawData(); + ImGui_ImplVulkan_RenderDrawData(draw_data, command_buffer); +} + +inline void imgui_shutdown() +{ + ImGui_ImplVulkan_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); +} + } diff --git a/src/inferno.cpp b/src/inferno.cpp index 901da96..0df7059 100644 --- a/src/inferno.cpp +++ b/src/inferno.cpp @@ -97,8 +97,6 @@ InfernoApp* inferno_create() app->Renderer = graphics::renderer_create(app->Device); graphics::renderer_configure_command_buffer(app->Renderer); - gui::imgui_init(app->Device); - app->Shader = graphics::shader_create(app->Device, app->Renderer->Swap); graphics::shader_load(app->Shader, "res/shaders/basic"); graphics::shader_build(app->Shader); @@ -400,7 +398,6 @@ int inferno_run(InfernoApp* app) inferno_end(app); inferno_timer_end(app->MainTimer); } - // return 1; } diff --git a/src/renderer/renderer.hpp b/src/renderer/renderer.hpp index b44dd63..3128eb5 100644 --- a/src/renderer/renderer.hpp +++ b/src/renderer/renderer.hpp @@ -39,7 +39,6 @@ void rayr_set_viewport(RayRenderer* renderer, Camera* camera); GLuint rayr_get_rendered_texture(RayRenderer* renderer); glm::fvec4* rayr_get_render_data(RayRenderer* renderer); - void rayr_draw(RayRenderer* renderer); void raryr_compute_hit(HitInfo* info); diff --git a/src/window.cpp b/src/window.cpp index 439c1ca..a1cbe82 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -6,7 +6,6 @@ #include #include -#include "imgui/imgui_impl_glfw.h" #include "yolo/yolo.hpp" #include @@ -122,24 +121,12 @@ bool window_new_frame() glfwGetWindowSize(Window, &Width, &Height); - // ImGui_ImplVulkan_NewFrame(); - // ImGui_ImplGlfw_NewFrame(); - // ImGui::NewFrame(); - // - // ImGui::Begin("main", nullptr, WINDOW_FLAGS); - // ImGui::SetWindowPos(ImVec2(0, 0)); - // ImGui::SetWindowSize(ImVec2(Width, Height)); - return true; } void window_render() { - // ImGui::End(); - // ImGui::Render(); - // auto io = ImGui::GetIO(); - // ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData()); - // glfwSwapBuffers(Window); - // ImGui::UpdatePlatformWindows(); + glfwSwapBuffers(Window); + ImGui::UpdatePlatformWindows(); } }