Karma Engine
Loading...
Searching...
No Matches
KarmaGuiVulkanHandler.h
1// Major and heavy modifications of the original Dear ImGUI's take on Vulkan implementation
2// https://github.com/ravimohan1991/imgui/blob/9068fd1afbaba56247aacd452bbadebb286800c7/backends/imgui_impl_vulkan.h
3
4#pragma once
5
6#include "krpch.h"
7
8#include "KarmaGui.h"
9#include "KarmaGuiInternal.h"
10#include "Karma/Renderer/Scene.h"
11#include <vulkan/vulkan.h>
12
13namespace Karma
14{
15 // Initialization data, for ImGui_ImplVulkan_Init()
16 // [Please zero-clear before use!]
18 {
19 VkInstance Instance;
20 VkPhysicalDevice PhysicalDevice;
21 VkDevice Device;
22 uint32_t QueueFamily;
23 VkQueue Queue;
24 VkPipelineCache PipelineCache;
25 VkDescriptorPool DescriptorPool;
26 VkRenderPass RenderPass; // Very experimental here
27 uint32_t Subpass;
28 uint32_t MinImageCount; // >= 2
29 uint32_t ImageCount; // >= MinImageCount
30 VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
31 const VkAllocationCallbacks* Allocator;
32 };
33
34 //-------------------------------------------------------------------------
35 // Internal / Miscellaneous Vulkan Helpers
36 // (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.)
37 //-------------------------------------------------------------------------
38 // You probably do NOT need to use or care about those functions.
39 // Those functions only exist because:
40 // 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
41 // 2) the multi-viewport / platform window implementation needs them internally.
42 // Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
43 // but it is too much code to duplicate everywhere so we exceptionally expose them.
44 //
45 // Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
46 // You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
47 // (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
48 //-------------------------------------------------------------------------
49
50 // Cowboy's confusion clarification concept!
51 // It seems the ImGUI author(s) have mixed and/or confused notion of
52 // ImageCount, which decides the number of SwapChainImages, framebuffer, and so on (contained within
53 // ImGui_ImplVulkanH_ImageFrame structure).
54 // (https://vulkan-tutorial.com/Drawing_a_triangle/Presentation/Swap_chain#page_Retrieving-the-swap-chain-images)
55 // and MAX_FRAMES_IN_FLIGHT, which is representative of (linearly proportional to or indicative of) number of commandbuffer recordings on CPU that may happen whilst the rendering is being done on GPU. That should determine the semaphore, fence, and commandbuffer size.
56 // https://vulkan-tutorial.com/Drawing_a_triangle/Drawing/Frames_in_flight
57 // The argument is elicited by the comment line https://github.com/ravimohan1991/imgui/blob/e4967701b67edd491e884632f239ab1f38867d86/backends/imgui_impl_vulkan.h#L144
59 {
60 VkFence Fence;
61 VkSemaphore ImageAcquiredSemaphore;
62 VkSemaphore RenderCompleteSemaphore;
63 VkCommandBuffer CommandBuffer;
64 };
65
66 // Helper structure to hold the data needed by one rendering ImageFrame (different from the FRAME_IN_FLIGHT frame!)
67 // (Used by multi-viewport features. We gonna just use this.)
68 // [Please zero-clear before use!]
70 {
71 //VkCommandPool CommandPool;
72 //VkCommandBuffer CommandBuffer;
73 VkImage Backbuffer; // VulkanContext m_swapChainImages equivalent
74 VkImageView BackbufferView; // VulkanContext m_swapChainImageViews equivalent
75 VkFramebuffer Framebuffer;
76 };
77
78 // Helper structure to hold the data needed by one rendering context into one OS window
79 // Seems like the appropriate inherited instantiation of our Window class (written in Window.h),
80 // created in Application (https://github.com/ravimohan1991/KarmaEngine/blob/main/Karma/src/Karma/Application.cpp)
81 // (Used by multi-viewport features. We gonna just use this.)
83 {
84 int Width;
85 int Height;
86 VkSwapchainKHR Swapchain;
87 VkCommandPool CommandPool;
88 VkSurfaceKHR Surface;
89 VkSurfaceFormatKHR SurfaceFormat;
90 VkPresentModeKHR PresentMode;
91 VkRenderPass RenderPass;
92 VkPipeline Pipeline; // Caution: The window pipeline may use a different VkRenderPass than the one passed in ImGui_ImplVulkan_InitInfo. Need to investigate why.
93 bool ClearEnable;
94 VkClearValue ClearValue;
95 uint32_t ImageFrameIndex; // Number of the image (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count) to be addressed for frame (each loop iteration) rendering logic.
96 uint32_t TotalImageCount; // Total Number of the images supported by swapchain
97 uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores and command buffers we're using (0 <= SemaphoreIndex < MAX_FRAMES_IN_FLIGHT)
98 uint32_t MAX_FRAMES_IN_FLIGHT;
99 KarmaGui_ImplVulkanH_ImageFrame* ImageFrames; // Cowboy's Note: Not the regular frame sense. Just a container for buffers and all those sizes depending on VulkanHolder::GetVulkanContext()->GetSwapChainImages().size();
100
101 // Cowboy's Modification
102 KarmaGui_Vulkan_Frame_On_Flight* FramesOnFlight; // The syncronicity data for in-flight frames
103 VkRect2D RenderArea;
104
106 {
107 memset((void*)this, 0, sizeof(*this));
108 PresentMode = (VkPresentModeKHR)~0; // Ensure we get an error if user doesn't set this.
109 ClearEnable = true;
110 }
111 };
112
113 // Reusable buffers used for rendering 1 current in-flight ImageFrame, for ImGui_ImplVulkan_RenderDrawData()
114 // Seems like data structure with single instantiation for each of the FrameIndex
115 // [Please zero-clear before use!]
117 {
118 VkDeviceMemory VertexBufferMemory;
119 VkDeviceMemory IndexBufferMemory;
120 VkDeviceSize VertexBufferSize;
121 VkDeviceSize IndexBufferSize;
122 VkBuffer VertexBuffer;
123 VkBuffer IndexBuffer;
124
125 public:
127 {
128 VertexBufferSize = IndexBufferSize = 0;
129 IndexBuffer = VertexBuffer = VK_NULL_HANDLE;
130 IndexBufferMemory = VertexBufferMemory = VK_NULL_HANDLE;
131 }
132 };
133
134 // Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
135 // [Please zero-clear before use!]
137 {
138 uint32_t Index;
139 uint32_t Count;
141 };
142
143 // For multi-viewport support:
144 // Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data.
146 {
147 bool WindowOwned;
148 KarmaGui_ImplVulkanH_Window Window; // Used by secondary viewports only
149 KarmaGui_ImplVulkanH_WindowRenderBuffers RenderBuffers; // Used by all viewports
150 //ImGui_ImplVulkanH_Window* ImGUILayerWindowData;
151
153 {
154 WindowOwned = false;
155 memset(&RenderBuffers, 0, sizeof(RenderBuffers));
156 }
158 };
159
160 // Vulkan Image data
162 {
163 std::string TextureLable;
164 uint32_t width;
165 uint32_t height;
166 uint32_t channels;
167 size_t size;
168
169 VkSampler TextureSampler;
170 VkDeviceMemory TextureMemory;
171 VkImage TextureImage;
172 VkImageView TextureView;
173 VkDescriptorSet TextureDescriptorSet;
174 VkDeviceMemory UploadBufferMemory;
175 VkBuffer UploadBuffer;
176
178 {
179 TextureLable = "NO LABLE YET";
180 }
181 };
182
183 // Vulkan data
184 // Seems for single ImGUI context (which can have multiple window)
186 {
187 KarmaGui_ImplVulkan_InitInfo VulkanInitInfo;
188 VkRenderPass RenderPass;
189 VkDeviceSize BufferMemoryAlignment;
190 VkPipelineCreateFlags PipelineCreateFlags;
191 VkDescriptorSetLayout DescriptorSetLayout;
192 VkPipelineLayout PipelineLayout;
193 VkPipeline Pipeline;
194 uint32_t Subpass;
195 VkShaderModule ShaderModuleVert;
196 VkShaderModule ShaderModuleFrag;
197
198 // Font data
199 VkSampler FontSampler;
200 VkDeviceMemory FontMemory;
201 VkImage FontImage;
202 VkImageView FontView;
203 VkDescriptorSet FontDescriptorSet;
204 VkDeviceMemory UploadBufferMemory;
205 VkBuffer UploadBuffer;
206
207 // Image data
208 std::vector<KarmaGui_ImplVulkan_Image_TextureData*> vulkanMesaDecalDataList;
209
210 // Render buffers for main window
211 KarmaGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers;
212
213 // heh, not working with initializers in MSVC. Need a blog post!
214
215 /*
216 ImGui_ImplVulkan_Data()
217 {
218 memset((void*)this, 0, sizeof(*this));
219 BufferMemoryAlignment = 256;
220 }*/
221 };
222
223 class KARMA_API KarmaGuiVulkanHandler
224 {
225 public:
226 /*
227 inline static KarmaGui_ImplVulkan_Data* KarmaGui_ImplVulkan_GetBackendData()
228 {
229 return KarmaGui::GetCurrentContext() ? (KarmaGui_ImplVulkan_Data*)KarmaGui::GetIO().BackendRendererUserData : nullptr;
230 }*/
231 // GetIO should fetche the configuration settings and whatnot, which in this case is the struct KarmaGui_ImplVulkan_Data
232
233 static uint32_t KarmaGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits);
234 static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& bufferMemory, VkDeviceSize& pBufferSize, size_t newSize, VkBufferUsageFlagBits usage);
235 static void KarmaGui_ImplVulkan_SetupRenderState(KGDrawData* drawData, VkPipeline pipeline, VkCommandBuffer commandBuffer, KarmaGui_ImplVulkanH_ImageFrameRenderBuffers* remderingBufferData, int width, int height);
236
237 // Experimental
238 static void KarmaGui_ImplVulkan_SetupRenderStateFor3DRendering(Scene* sceneToDraw, VkCommandBuffer commandBuffer, KGDrawData* drawData);
239
240 static void KarmaGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAllocationCallbacks* allocator);
241 static void KarmaGui_ImplVulkan_CreateFontSampler(VkDevice device, const VkAllocationCallbacks* allocator);
242 static void KarmaGui_ImplVulkan_CreateDescriptorSetLayout(VkDevice device, const VkAllocationCallbacks* allocator);
243 static void KarmaGui_ImplVulkan_CreatePipelineLayout(VkDevice device, const VkAllocationCallbacks* allocator);
244 static void KarmaGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationCallbacks* allocator, VkPipelineCache pipelineCache, VkRenderPass renderPass, VkSampleCountFlagBits MSAASamples, VkPipeline* pipeline, uint32_t subpass);
245 static void KarmaGui_ImplVulkan_CreateWindow(KarmaGuiViewport* viewport);
246
247 // Overload
248 static void KarmaGui_ImplVulkan_DestroyWindow(KarmaGuiViewport* viewport);
249 static void KarmaGui_ImplVulkan_DestroyWindow(KarmaGui_ImplVulkanH_Window* windowData);
250
251 static void KarmaGui_ImplVulkan_SetWindowSize(KarmaGuiViewport* viewport, KGVec2 size);
252 static void KarmaGui_ImplVulkan_RenderWindow(KarmaGuiViewport* viewport, void*);
253 static void KarmaGui_ImplVulkan_RenderDrawData(KGDrawData* drawData, VkCommandBuffer commandBuffer, VkPipeline pipeline, uint32_t imageFrameIndex);
254 static void KarmaGui_ImplVulkan_SwapBuffers(KarmaGuiViewport* viewport, void*);
255 static void ShareVulkanContextResourcesOfMainWindow(KarmaGui_ImplVulkanH_Window* windowData, bool bCreateSyncronicity = false);
256 static void ClearVulkanWindowData(KarmaGui_ImplVulkanH_Window* vulkanWindowData, bool bDestroySyncronicity = false);
257 static void DestroyWindowDataFrame(KarmaGui_ImplVulkanH_ImageFrame* frame);
258 static void DestroyFramesOnFlightData(KarmaGui_Vulkan_Frame_On_Flight* frameSyncronicityData);
259 static void KarmaGui_ImplVulkan_CreateOrResizeWindow(KarmaGui_ImplVulkanH_Window* windowData, bool bCreateSyncronicity, bool bRecreateSwapChainAndCommandBuffers);
260 static void KarmaGui_ImplVulkan_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator);
261 static void KarmaGui_ImplVulkan_ShivaWindowRenderBuffers(VkDevice device, KarmaGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
262 static void KarmaGui_ImplVulkan_ShivaFrameRenderBuffers(VkDevice device, KarmaGui_ImplVulkanH_ImageFrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
263
264 static bool KarmaGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer commandBuffer);
265 static bool KarmaGui_ImplVulkan_CreateTexture(VkCommandBuffer commandBuffer, char const* fileName, const std::string& lable = "");
266
267 static bool KarmaGui_ImplVulkan_CreateDeviceObjects();
268 static void KarmaGui_ImplVulkan_DestroyFontUploadObjects();
269 static void KarmaGui_ImplVulkan_DestroyDeviceObjects();
270
271 static bool KarmaGui_ImplVulkan_Init(KarmaGui_ImplVulkan_InitInfo* info);
272 static void KarmaGui_ImplVulkan_Shutdown();
273 static void KarmaGui_ImplVulkan_NewFrame();
274
275 // Register a texture (VkDescriptorSet == ImTextureID)
276 // FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem, please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
277 static VkDescriptorSet KarmaGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout);
278 static void KarmaGui_ImplVulkan_InitPlatformInterface();
279 static void KarmaGui_ImplVulkan_ShutdownPlatformInterface();
280 };
281}
Definition Buffer.h:181
Definition KarmaGuiVulkanHandler.h:224
Definition Scene.h:11
Definition Buffer.h:167
Definition Window.h:27
Definition KarmaGui.h:2647
Definition KarmaGui.h:145
Definition KarmaGui.h:2948
Definition KarmaGuiVulkanHandler.h:117
Definition KarmaGuiVulkanHandler.h:70
Definition KarmaGuiVulkanHandler.h:137
Definition KarmaGuiVulkanHandler.h:83
Definition KarmaGuiVulkanHandler.h:186
Definition KarmaGuiVulkanHandler.h:162
Definition KarmaGuiVulkanHandler.h:18
Definition KarmaGuiVulkanHandler.h:146
Definition KarmaGuiVulkanHandler.h:59