154 lines
6.9 KiB
C++
154 lines
6.9 KiB
C++
#pragma once
|
|
#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES
|
|
#include <imgui.h>
|
|
#include <imgui_impl_sdl3.h>
|
|
#include <imgui_impl_vulkan.h>
|
|
#include <utils/log.hpp>
|
|
#include <memory>
|
|
|
|
namespace gui {
|
|
static VkAllocationCallbacks* g_Allocator = NULL;
|
|
static VkInstance g_Instance = VK_NULL_HANDLE;
|
|
static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE;
|
|
static VkDevice g_Device = VK_NULL_HANDLE;
|
|
static uint32_t g_QueueFamily = (uint32_t)-1;
|
|
static VkQueue g_Queue = VK_NULL_HANDLE;
|
|
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
|
|
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
|
|
|
static ImGui_ImplVulkanH_Window g_MainWindowData;
|
|
static uint32_t g_MinImageCount = 2;
|
|
|
|
inline std::shared_ptr<Vulkan::WSI> g_Wsi;
|
|
|
|
static void CheckVkResult(VkResult err) {
|
|
if (err == 0)
|
|
return;
|
|
Util::error("[vulkan] VkResult = {}", (int) err);
|
|
if (err < 0)
|
|
abort();
|
|
}
|
|
|
|
inline void Initialize(const std::shared_ptr<Vulkan::WSI>& wsi, SDL_Window* nativeWindow) {
|
|
VkResult err;
|
|
g_Wsi = wsi;
|
|
// Setup Dear ImGui context
|
|
IMGUI_CHECKVERSION();
|
|
ImGui::CreateContext();
|
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
|
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
|
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
|
|
|
// Setup Dear ImGui style
|
|
ImGui::StyleColorsDark();
|
|
//ImGui::StyleColorsClassic();
|
|
|
|
g_Instance = wsi->get_context().get_instance();
|
|
g_PhysicalDevice = wsi->get_device().get_physical_device();
|
|
g_Device = wsi->get_device().get_device();
|
|
g_QueueFamily = wsi->get_context().get_queue_info().family_indices[Vulkan::QUEUE_INDEX_GRAPHICS];
|
|
g_Queue = wsi->get_context().get_queue_info().queues[Vulkan::QUEUE_INDEX_GRAPHICS];
|
|
g_PipelineCache = nullptr;
|
|
g_DescriptorPool = nullptr;
|
|
g_Allocator = nullptr;
|
|
g_MinImageCount = 2;
|
|
|
|
|
|
// Create Descriptor Pool
|
|
{
|
|
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 * IM_ARRAYSIZE(pool_sizes);
|
|
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
|
|
pool_info.pPoolSizes = pool_sizes;
|
|
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
|
|
CheckVkResult(err);
|
|
}
|
|
|
|
// Create the Render Pass
|
|
VkRenderPass renderPass;
|
|
{
|
|
VkAttachmentDescription attachment = {};
|
|
attachment.format = wsi->get_device().get_swapchain_view().get_format();
|
|
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
VkAttachmentReference color_attachment = {};
|
|
color_attachment.attachment = 0;
|
|
color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
VkSubpassDescription subpass = {};
|
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
|
subpass.colorAttachmentCount = 1;
|
|
subpass.pColorAttachments = &color_attachment;
|
|
VkSubpassDependency dependency = {};
|
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
|
dependency.dstSubpass = 0;
|
|
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
dependency.srcAccessMask = 0;
|
|
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
VkRenderPassCreateInfo info = {};
|
|
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
|
info.attachmentCount = 1;
|
|
info.pAttachments = &attachment;
|
|
info.subpassCount = 1;
|
|
info.pSubpasses = &subpass;
|
|
info.dependencyCount = 1;
|
|
info.pDependencies = &dependency;
|
|
err = vkCreateRenderPass(g_Device, &info, g_Allocator, &renderPass);
|
|
CheckVkResult(err);
|
|
}
|
|
// Setup Platform/Renderer backends
|
|
ImGui_ImplSDL3_InitForVulkan(nativeWindow);
|
|
ImGui_ImplVulkan_InitInfo init_info = {};
|
|
init_info.Instance = g_Instance;
|
|
init_info.PhysicalDevice = g_PhysicalDevice;
|
|
init_info.Device = g_Device;
|
|
init_info.QueueFamily = g_QueueFamily;
|
|
init_info.Queue = g_Queue;
|
|
init_info.PipelineCache = g_PipelineCache;
|
|
init_info.DescriptorPool = g_DescriptorPool;
|
|
init_info.Allocator = g_Allocator;
|
|
init_info.MinImageCount = g_MinImageCount;
|
|
init_info.ImageCount = 2;
|
|
init_info.CheckVkResultFn = CheckVkResult;
|
|
init_info.RenderPass = renderPass;
|
|
init_info.ApiVersion = VK_API_VERSION_1_3;
|
|
|
|
ImGui_ImplVulkan_LoadFunctions(VK_API_VERSION_1_3, [](const char *function_name, void *vulkan_instance) {
|
|
return vkGetInstanceProcAddr((reinterpret_cast<VkInstance>(vulkan_instance)), function_name);
|
|
}, g_Instance);
|
|
|
|
if(!ImGui_ImplVulkan_Init(&init_info))
|
|
Util::panic("Failed to initialize ImGui!");
|
|
}
|
|
|
|
inline void StartFrame() {
|
|
ImGui_ImplVulkan_NewFrame();
|
|
ImGui_ImplSDL3_NewFrame();
|
|
ImGui::NewFrame();
|
|
}
|
|
|
|
inline void EndFrame() {
|
|
}
|
|
} |