114 lines
3.9 KiB
C++
114 lines
3.9 KiB
C++
#include "vk_renderpass_imgui.h"
|
|
|
|
#include "imgui.h"
|
|
#include "imgui_impl_sdl2.h"
|
|
#include "imgui_impl_vulkan.h"
|
|
#include "vk_device.h"
|
|
#include "vk_swapchain.h"
|
|
#include "core/vk_initializers.h"
|
|
#include "core/engine_context.h"
|
|
#include "render/rg_graph.h"
|
|
|
|
void ImGuiPass::init(EngineContext *context)
|
|
{
|
|
_context = context;
|
|
|
|
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},
|
|
{VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000},
|
|
{VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000},
|
|
{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000},
|
|
{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}
|
|
};
|
|
|
|
VkDescriptorPoolCreateInfo pool_info = {};
|
|
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
|
pool_info.maxSets = 1000;
|
|
pool_info.poolSizeCount = (uint32_t) std::size(pool_sizes);
|
|
pool_info.pPoolSizes = pool_sizes;
|
|
|
|
VkDescriptorPool imguiPool;
|
|
VK_CHECK(vkCreateDescriptorPool(_context->device->device(), &pool_info, nullptr, &imguiPool));
|
|
|
|
ImGui::CreateContext();
|
|
|
|
ImGui_ImplSDL2_InitForVulkan(_context->window);
|
|
|
|
ImGui_ImplVulkan_InitInfo init_info = {};
|
|
init_info.Instance = _context->getDevice()->instance();
|
|
init_info.PhysicalDevice = _context->getDevice()->physicalDevice();
|
|
init_info.Device = _context->getDevice()->device();
|
|
init_info.Queue = _context->getDevice()->graphicsQueue();
|
|
init_info.DescriptorPool = imguiPool;
|
|
init_info.MinImageCount = 3;
|
|
init_info.ImageCount = 3;
|
|
init_info.UseDynamicRendering = true;
|
|
|
|
init_info.PipelineRenderingCreateInfo = {.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO};
|
|
init_info.PipelineRenderingCreateInfo.colorAttachmentCount = 1;
|
|
auto _swapchainImageFormat = _context->getSwapchain()->swapchainImageFormat();
|
|
init_info.PipelineRenderingCreateInfo.pColorAttachmentFormats = &_swapchainImageFormat;
|
|
|
|
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
ImGui_ImplVulkan_Init(&init_info);
|
|
|
|
ImGui_ImplVulkan_CreateFontsTexture();
|
|
|
|
// add the destroy the imgui created structures
|
|
_deletionQueue.push_function([=]() {
|
|
ImGui_ImplVulkan_Shutdown();
|
|
vkDestroyDescriptorPool(_context->getDevice()->device(), imguiPool, nullptr);
|
|
});
|
|
}
|
|
|
|
void ImGuiPass::cleanup()
|
|
{
|
|
fmt::print("ImGuiPass::cleanup()\n");
|
|
_deletionQueue.flush();
|
|
}
|
|
|
|
void ImGuiPass::execute(VkCommandBuffer)
|
|
{
|
|
// ImGui is executed via the render graph now.
|
|
}
|
|
|
|
void ImGuiPass::register_graph(RenderGraph *graph, RGImageHandle swapchainHandle)
|
|
{
|
|
if (!graph || !swapchainHandle.valid()) return;
|
|
|
|
graph->add_pass(
|
|
"ImGui",
|
|
RGPassType::Graphics,
|
|
[swapchainHandle](RGPassBuilder &builder, EngineContext *)
|
|
{
|
|
builder.write_color(swapchainHandle, false, {});
|
|
},
|
|
[this, swapchainHandle](VkCommandBuffer cmd, const RGPassResources &res, EngineContext *ctx)
|
|
{
|
|
draw_imgui(cmd, ctx, res, swapchainHandle);
|
|
});
|
|
}
|
|
|
|
void ImGuiPass::draw_imgui(VkCommandBuffer cmd,
|
|
EngineContext *context,
|
|
const RGPassResources &resources,
|
|
RGImageHandle targetHandle) const
|
|
{
|
|
EngineContext *ctxLocal = context ? context : _context;
|
|
if (!ctxLocal) return;
|
|
|
|
VkImageView targetImageView = resources.image_view(targetHandle);
|
|
if (targetImageView == VK_NULL_HANDLE) return;
|
|
|
|
// Dynamic rendering is handled by the RenderGraph; just render draw data.
|
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);
|
|
}
|