Polyphase Game Engine
Loading...
Searching...
No Matches
VulkanContext.h
Go to the documentation of this file.
1#pragma once
2
3#if API_VULKAN
4
5#include <vulkan/vulkan.h>
6#include <stb_image.h>
7
8#include "VulkanUtils.h"
9#include "MultiBuffer.h"
10#include "DescriptorSet.h"
11#include "Pipeline.h"
12#include "PipelineConfigs.h"
13#include "VramAllocator.h"
14#include "DestroyQueue.h"
15#include "Buffer.h"
16#include "Image.h"
17#include "Line.h"
18#include "SmartPointer.h"
19#include "RayTracer.h"
20#include "Profiler.h"
21#include "DescriptorPool.h"
23#include "PipelineCache.h"
24#include "RenderPassCache.h"
25#include "PostProcessChain.h"
26
27#if PLATFORM_LINUX
28#include <xcb/xcb.h>
29#include <vulkan/vulkan_xcb.h>
30#elif PLATFORM_MAC
31#include <vulkan/vulkan_metal.h>
32#endif
33
34struct EngineState;
35class World;
36
37struct QueueFamilyIndices
38{
39 int32_t mGraphicsFamily = -1;
40 int32_t mPresentFamily = -1;
41
42 bool IsComplete()
43 {
44 return mGraphicsFamily >= 0 &&
45 mPresentFamily >= 0;
46 }
47};
48
49struct SwapChainSupportDetails
50{
51 VkSurfaceCapabilitiesKHR capabilities;
52 std::vector<VkSurfaceFormatKHR> formats;
53 std::vector<VkPresentModeKHR> presentModes;
54};
55
56struct GpuTimespan
57{
58 std::string mName;
59 int32_t mStartIndex = -1;
60 int32_t mEndIndex = -1;
61};
62
63class VulkanContext
64{
65
66public:
67
68 VulkanContext();
69 ~VulkanContext();
70
71 void Initialize();
72 void Destroy();
73
74#if EDITOR
75 // Re-uploads the ImGui font atlas after io.Fonts was rebuilt. Call outside an ImGui frame.
76 void RebuildImguiFontTexture();
77#endif
78
79 void BeginFrame();
80 void EndFrame();
81 void BeginRenderPass(RenderPassId id);
82 void BeginVkRenderPass(const RenderPassSetup& rpSetup, bool insertBarrier, glm::vec4 clearColor = {});
83 void EndRenderPass();
84 void EndVkRenderPass();
85 bool IsVkRenderPassActive() const { return mVkRenderPassActive; }
86 void CommitPipeline();
87 void DrawLines(const std::vector<Line>& lines);
88 void DrawSplats(const struct GaussianSplatInstance* instances, uint32_t count,
89 const glm::vec3& cameraRight, const glm::vec3& cameraUp);
90 void DrawFullscreen();
91 void BindFullscreenVertexBuffer(VkCommandBuffer cb);
92
93 VkDevice GetDevice();
94 void CreateSwapchain();
95 void RecreateSwapchain(bool recreateSurface, const char* reason = "unspecified");
96
97 VkPhysicalDevice GetPhysicalDevice();
98 DescriptorPool& GetDescriptorPool();
99 DescriptorLayoutCache& GetDescriptorLayoutCache();
100
101 DestroyQueue* GetDestroyQueue();
102
103 VkExtent2D& GetSwapchainExtent();
104 VkFormat GetSwapchainFormat();
105 VkFormat GetSceneColorFormat();
106 Image* GetSceneColorImage();
107 Image* GetSwapchainImage();
108
109 Pipeline* GetBoundPipeline();
110 PipelineCache& GetPipelineCache();
111 void SavePipelineCacheToFile();
112
113 void SetViewport(int32_t x, int32_t y, int32_t width, int32_t height, bool handlePrerotation, bool useSceneRes);
114 void SetScissor(int32_t x, int32_t y, int32_t width, int32_t height, bool handlePrerotation, bool useSceneRes);
115
116 void CreateCommandBuffers();
117
118 uint32_t GetFrameIndex() const;
119 uint32_t GetFrameNumber() const;
120
121 void SetMultiBufferFrameOffset(uint32_t offset) { mMultiBufferFrameOffset = offset; }
122 uint32_t GetMultiBufferFrameOffset() const { return mMultiBufferFrameOffset; }
123 RenderPassId GetCurrentRenderPassId() const;
124
125 Image* GetShadowMapImage();
126
127 VkCommandBuffer GetCommandBuffer();
128 VkCommandPool GetCommandPool();
129 VkQueue GetGraphicsQueue();
130
131 // Used by GFX_GetVulkanAddonHandles — exposes the render pass the engine
132 // is mid-recording on so an addon can build a pipeline compatible with it.
133 // Defined out-of-line below so it can see mPipelineState (declared private,
134 // further down in this header). GetFrameIndex() already exists at line 110.
135 VkRenderPass GetCurrentRenderPass() const;
136
137 void UpdateGlobalDescriptorSet();
138 void UpdateGlobalUniformData();
139
140 void BindGlobalDescriptorSet();
141
142 GlobalUniformData& GetGlobalUniformData();
143
144 bool IsValidationEnabled() const;
145 bool IsRayTracingSupported() const;
146 bool HasFeatureWideLines() const;
147 bool HasFeatureFillModeNonSolid() const;
148
149 bool AreMaterialsEnabled() const;
150 void EnableMaterials(bool enable);
151
152 void BeginGpuTimestamp(const char* name);
153 void EndGpuTimestamp(const char* name);
154 void ReadTimeQueryResults();
155
156 RayTracer* GetRayTracer();
157 PostProcessChain* GetPostProcessChain();
158
159 void RenderPostProcessChain();
160
161 VkSurfaceTransformFlagBitsKHR GetPreTransformFlag() const;
162
163 uint32_t GetSceneWidth();
164 uint32_t GetSceneHeight();
165
166 const VkPhysicalDeviceProperties& GetDeviceProperties() const;
167 UniformBuffer* GetFrameUniformBuffer();
168
169 Shader* GetGlobalShader(const std::string& name);
170
171 // Pipeline State
172 const PipelineState& GetPipelineState() const;
173 void SetPipelineState(const PipelineState& state);
174 void SetVertexShader(Shader* shader);
175 void SetFragmentShader(Shader* shader);
176 void SetComputeShader(Shader* shader);
177 void SetVertexShader(const std::string& globalName);
178 void SetFragmentShader(const std::string& globalName);
179 void SetComputeShader(const std::string& globalName);
180 void SetRenderPass(VkRenderPass renderPass);
181 void SetVertexType(VertexType vertexType);
182 void SetRasterizerDiscard(bool discard);
183 void SetPrimitiveTopology(VkPrimitiveTopology primitiveToplogy);
184 void SetPolygonMode(VkPolygonMode polygonMode);
185 void SetLineWidth(float lineWidth);
186 void SetDynamicLineWidth(bool dynamicLineWidth);
187 void SetCullMode(VkCullModeFlags cullMode);
188 void SetFrontFace(VkFrontFace frontFace);
189 void SetDepthBias(float depthBias);
190 void SetDepthTestEnabled(bool enabled);
191 void SetDepthWriteEnabled(bool enabled);
192 void SetDepthCompareOp(VkCompareOp compareOp);
193 void SetBlendState(VkPipelineColorBlendAttachmentState blendState, uint32_t index = 0);
194 void SetBlendState(BasicBlendState basicBlendState, uint32_t index = 0);
195 void SetBlendEnable(bool enable, uint32_t index = 0);
196 void SetBlendColorOp(VkBlendFactor src, VkBlendFactor dst, VkBlendOp op, uint32_t index = 0);
197 void SetBlendAlphaOp(VkBlendFactor src, VkBlendFactor dst, VkBlendOp op, uint32_t index = 0);
198 void SetColorWriteMask(VkColorComponentFlags writeMask, uint32_t index = 0);
199
200
201private:
202
203 static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(
204 VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
205 VkDebugUtilsMessageTypeFlagsEXT messageType,
206 const VkDebugUtilsMessengerCallbackDataEXT* callbackData,
207 void* userData);
208
209 void CreateInstance();
210 void CreateDebugCallback();
211 void CreateSurface();
212 void CreateLogicalDevice();
213 void CreateFrameUniformBuffer();
214 void DestroyFrameUniformBuffer();
215 void CreateRenderPasses();
216 void DestroyRenderPasses();
217 void CreateCommandPool();
218 void CreateSemaphores();
219 void CreateFences();
220 void CreateDescriptorPools();
221 void DestroyDescriptorPools();
222 void CreateDepthImage();
223 void CreateSceneColorImage();
224 void CreateShadowMapImage();
225 void CreateQueryPools();
226 void DestroyQueryPools();
227 void RecreateSurface();
228 void CreateGlobalShaders();
229 void DestroyGlobalShaders();
230 void CreateMisc();
231 void DestroyMisc();
232
233 void PickPhysicalDevice();
234 bool IsDeviceSuitable(VkPhysicalDevice device);
235 VkSurfaceFormatKHR ChooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
236 VkPresentModeKHR ChooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availableModes);
237 VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
238 QueueFamilyIndices FindQueueFamilies(VkPhysicalDevice device);
239 SwapChainSupportDetails QuerySwapChainSupport(VkPhysicalDevice device);
240
241 bool CheckValidationLayerSupport(
242 const char** layers,
243 uint32_t count);
244 bool CheckDeviceExtensionSupport(
245 VkPhysicalDevice device,
246 const char** extensions,
247 uint32_t count);
248
249 void DestroySwapchain();
250 // True when the surface's current extent differs from mSwapchainExtent.
251 bool SurfaceExtentChanged();
252 void DestroyDebugCallback();
253
254private:
255
256 // Core
257 VkInstance mInstance = VK_NULL_HANDLE;
258 VkDebugReportCallbackEXT mCallback = VK_NULL_HANDLE;
259 VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
260 VkDevice mDevice = VK_NULL_HANDLE;
261 VkQueue mGraphicsQueue = VK_NULL_HANDLE;
262 VkQueue mPresentQueue = VK_NULL_HANDLE;
263 VkSurfaceKHR mSurface = VK_NULL_HANDLE;
264 uint32_t mGraphicsQueueFamily = 0;
265 uint32_t mPresentQueueFamily = 0;
266
267 // Descriptors
268 DescriptorPool mDescriptorPools[MAX_FRAMES];
269 DescriptorLayoutCache mDescriptorLayoutCache;
270 VkDescriptorPool mImguiDescriptorPool = VK_NULL_HANDLE;
271
272 // Command Buffers
273 VkCommandPool mCommandPool = VK_NULL_HANDLE;
274 std::vector<VkCommandBuffer> mCommandBuffers;
275
276 // Swapchain
277 VkSwapchainKHR mSwapchain = VK_NULL_HANDLE;
278 std::vector<VkImage> mSwapchainImages;
279 std::vector<VkImageView> mSwapchainImageViews;
280 VkFormat mSwapchainImageFormat = VK_FORMAT_UNDEFINED;
281 VkExtent2D mSwapchainExtent = {};
282 std::vector<Image*> mExtSwapchainImages;
283 // Previous swapchain, kept alive across a recreate so it can be handed to
284 // VkSwapchainCreateInfoKHR::oldSwapchain (the driver reuses its drawables
285 // instead of tearing the pool down), then destroyed once the new one exists.
286 VkSwapchainKHR mRetiredSwapchain = VK_NULL_HANDLE;
287 // Presents that returned VK_SUBOPTIMAL_KHR without a surface size change
288 // since the last (re)create. Logged once; see EndFrame.
289 uint32_t mSuboptimalIgnored = 0;
290
291 // RenderPasses
292 RenderPassCache mRenderPassCache;
293 VkRenderPass mImguiRenderPass = VK_NULL_HANDLE;
294
295 // Images
296 Image* mShadowMapImage = nullptr;
297 Image* mSceneColorImage = nullptr;
298 VkFormat mSceneColorImageFormat;
299 Image* mDepthImage = nullptr;
300 VkFormat mDepthImageFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
301
302 // Synchronization
303 VkSemaphore mImageAvailableSemaphore[MAX_FRAMES] = {};
304 VkSemaphore mRenderFinishedSemaphore[MAX_FRAMES] = {};
305 VkFence mWaitFences[MAX_FRAMES] = {};
306
307 // Pipelines
308 PipelineCache mPipelineCache;
309 Pipeline* mBoundPipeline = nullptr;
310
311 // Shader Data
312 std::unordered_map<std::string, Shader*> mGlobalShaders;
313 DescriptorSet mGlobalDescriptorSet;
314 DescriptorSet mDebugDescriptorSet;
315 DescriptorSet mPostProcessDescriptorSet;
316 UniformBuffer* mFrameUniformBuffer = nullptr;
317 GlobalUniformData mGlobalUniformData;
318
319 // Destroy Queue
320 DestroyQueue mDestroyQueue;
321
322 // Ray Tracer
323 RayTracer mRayTracer;
324
325 // Debug
326 bool mValidate;
327 VkDebugUtilsMessengerEXT mDebugMessenger = VK_NULL_HANDLE;
328 uint32_t mEnabledExtensionCount = 0;
329 const char* mEnabledExtensions[MAX_ENABLED_EXTENSIONS] = { };
330 uint32_t mEnabledLayersCount = 0;
331 const char* mEnabledLayers[MAX_ENABLED_LAYERS] = { };
332
333 // Timestamp Queries
334 std::vector<GpuTimespan> mGpuTimespans[MAX_FRAMES];
335 VkQueryPool mTimeQueryPools[MAX_FRAMES] = { };
336 int32_t mNumTimestamps[MAX_FRAMES] = { };
337 float mTimestampPeriod = 0.0f;
338 bool mTimestampsSupported = false;
339
340 //Pipeline State
341 PipelineState mPipelineState;
342
343 // PostProcess
344 PostProcessChain mPostProcessChain;
345
346 // Misc
347 int32_t mFrameIndex = 0;
348 int32_t mFrameNumber = 0;
349 uint32_t mSwapchainImageIndex = 0;
350 RenderPassId mCurrentRenderPassId = RenderPassId::Count;
351 bool mVkRenderPassActive = false;
352 int32_t mNumLinesAllocated = 0;
353 Buffer* mLineVertexBuffer = nullptr;
354 int32_t mNumSplatsAllocated = 0;
355 Buffer* mSplatVertexBuffer = nullptr;
356 bool mInitialized = false;
357 bool mEnableMaterials = false;
358 bool mSupportsRayTracing = false;
359 bool mFeatureWideLines = false;
360 bool mFeatureFillModeNonSolid = false;
361 EngineState* mEngineState = nullptr;
362 VkSurfaceTransformFlagBitsKHR mPreTransformFlag = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
363 uint32_t mMultiBufferFrameOffset = 0;
364 float mResolutionScale = 1.0f;
365 uint32_t mSceneWidth = 0;
366 uint32_t mSceneHeight = 0;
367 VkPhysicalDeviceProperties mDeviceProperties;
368 Buffer* mFullScreenVertexBuffer = nullptr;
369
370#if EDITOR
371public:
372 class Node3D* ProcessHitCheck(World* world, int32_t pixelX, int32_t pixelY, uint32_t* outInstance = nullptr);
373private:
374 void CreateHitCheck();
375 void DestroyHitCheck();
376
377 Image* mHitCheckImage = nullptr;
378 Buffer* mHitCheckBuffer = nullptr;
379#endif
380
381};
382
383void CreateVulkanContext();
384void DestroyVulkanContext();
385VulkanContext* GetVulkanContext();
386
387#endif
bool Initialize()
Definition Engine.cpp:635
RenderPassId
Definition GraphicsTypes.h:90
VertexType
Definition Vertex.h:7
#define MAX_ENABLED_LAYERS
Definition VulkanConstants.h:4
#define MAX_ENABLED_EXTENSIONS
Definition VulkanConstants.h:3
BasicBlendState
Definition VulkanTypes.h:21
uint32_t GetFrameNumber()
Definition VulkanUtils.cpp:335
VkCommandBuffer GetCommandBuffer()
Definition VulkanUtils.cpp:350
uint32_t GetFrameIndex()
Definition VulkanUtils.cpp:330
DestroyQueue * GetDestroyQueue()
Definition VulkanUtils.cpp:340
Definition DescriptorLayoutCache.h:8
Definition DescriptorPool.h:7
Definition Node3d.h:14
Definition PipelineCache.h:9
Definition PostProcessChain.h:10
Definition RayTracer.h:15
Definition RenderPassCache.h:59
Definition Shader.h:18
Definition World.h:26
void BeginFrame()
Definition ImGuizmo.cpp:1026
Definition EngineTypes.h:503
Definition Graphics.h:65
Definition VulkanTypes.h:120
Definition VulkanTypes.h:30
Definition VulkanTypes.h:85