2
3
4
5
9#include "Debugger/Aftermath/NsightAftermathGpuCrashTracker.h"
10#include "Debugger/Perf/NsightPerfGPUProfilerHUD.h"
11#include "Debugger/Perf/NsightPerfGPUProfilerContinuous.h"
12#include "Debugger/Perf/NsightPerfGPUProfilerReportGenerator.h"
13#include "Debugger/Perf/NsightPerfGPUProfilerOneshotCollection.h"
14#include "Render/Renderer/RendererManager.h"
15#include "Render/RendererResource/RendererResourcePool.h"
16#include "Systems/SlateSystem.h"
17#include "..\..\Core\Thread\ThreadModel.h"
19#include "Render/Renderer/SpecificRenderer/PreRenderer.h"
20#include "Render/Renderer/SpecificRenderer/RayTracingRenderer.h"
21#include "Render/Renderer/SpecificRenderer/BasePassRenderer.h"
22#include "Render/Renderer/SpecificRenderer/SlateRenderer.h"
23#include "Render/Renderer/SpecificRenderer/SceneComposeRenderer.h"
24#include "Render/Renderer/SpecificRenderer/WorldPickRenderer.h"
25#include "Render/Renderer/SpecificRenderer/SpriteRenderer.h"
26#include "Render/Renderer/SpecificRenderer/WorldPickStage2Renderer.h"
27#include "Render/Renderer/SpecificRenderer/ParticleRenderer.h"
28#include "Render/Renderer/SpecificRenderer/TestRenderer.h"
29#include "Render/Renderer/SpecificRenderer/RayTracingComposeRenderer.h"
30#include "Render/Renderer/SpecificRenderer/ViewportGridRenderer.h"
31#include "Render/Renderer/SpecificRenderer/PostProcessRenderer.h"
36
37
49
50
52 NSIGHTAFTERMATH_GPUCRASHTRACKER_INIT
56
57
59 m_VulkanWindows = std::make_unique<VulkanWindows> (m_VulkanState, initInfo);
60 m_VulkanInstance = std::make_unique<VulkanInstance> (m_VulkanState,
"app",
"engine");
61 m_VulkanDevice = std::make_shared<VulkanDevice> (m_VulkanState);
64
65
71 NSIGHTPERF_GPUPROFILERCONTINUOUS_CREATEINSTANCE(
m_VulkanState)
75 m_VmaAllocator = std::make_shared<VulkanMemoryAllocator>(m_VulkanState);
76 m_VulkanCommandPool = std::make_unique<VulkanCommandPool> (m_VulkanState);
77 m_VulkanCommandBuffer = std::make_unique<VulkanCommandBuffer> (m_VulkanState);
78 m_VulkanSwapChain = std::make_unique<VulkanSwapChain> (m_VulkanState, m_VulkanDevice);
82
83
85 m_VulkanDescriptorPool = VulkanDescriptorPool::Builder()
86 .SetPoolFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT | VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)
87 .AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000)
88 .AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000)
89 .AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000)
90 .AddPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000)
91 .AddPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1000)
92 .Build(m_VulkanState);
96
97
98
100 m_RendererResourcePool = std::make_shared<RendererResourcePool>();
104
105
107 ThreadModel::Get()->InitRHIThreadPool([&](std::shared_ptr<VulkanCmdThreadPool>& ptr) {
108 ptr = std::make_shared<VulkanCmdThreadPool>(m_VulkanState,
"RHIT");
113
114
116 RendererManager::Get()
117 .Push<PreRenderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
120 .Push<RayTracingRenderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
121 .Push<RayTracingComposeRenderer>(m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
124 .Push<BasePassRenderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
125 .Push<SceneComposeRenderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
126 .Push<PostProcessRenderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
127 .Push<ViewportGridRenderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
128 .Push<SpriteRenderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
129 .Push<WorldPickRenderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
130 .Push<WorldPickStage2Renderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
132 .Push<TestRenderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool)
133 .Push<SlateRenderer> (m_VulkanState, m_VulkanDescriptorPool, m_VulkanDevice, m_RendererResourcePool);
142
143
145 NSIGHTPERF_GPUPROFILERCONTINUOUS_RESET
146 NSIGHTPERF_GPUPROFILERREPORT_RESET(m_VulkanState)
147 NSIGHTPERF_GPUPROFILERONESHOT_QUIT
150
151
152 m_RendererResourcePool =
nullptr;
155
156
157 m_VulkanDescriptorPool =
nullptr;
160
161
164 .Pop(
"SlateRenderer")
167 .Pop(
"WorldPickStage2Renderer")
168 .Pop(
"WorldPickRenderer")
169 .Pop(
"SpriteRenderer")
170 .Pop(
"ViewportGridRenderer")
171 .Pop(
"PostProcessRenderer")
172 .Pop(
"SceneComposeRenderer")
173 .Pop(
"BasePassRenderer")
174 .Pop(
"RayTracingComposeRenderer")
175 .Pop(
"RayTracingRenderer")
185
186
187 int width = 0, height = 0;
188 glfwGetFramebufferSize(
m_VulkanState.m_Windows, &width, &height);
189 while (width == 0 || height == 0)
191 glfwGetFramebufferSize(
m_VulkanState.m_Windows, &width, &height);
196
197
201
202
206
207
215 VkFence fence[2] = { m_VulkanState.m_ComputeFence[frameInfo.m_FrameIndex], m_VulkanState.m_GraphicFence[frameInfo.m_FrameIndex] };
221
222
223 VK_CHECK(vkWaitForFences(m_VulkanState.m_Device, 2, fence, VK_TRUE, UINT64_MAX))
230
231
232 VK_CHECK(vkResetFences(m_VulkanState.m_Device, 2, fence))
236
237
238 const VkResult result = vkAcquireNextImageKHR(
239 m_VulkanState.m_Device ,
240 m_VulkanState.m_SwapChain ,
242 m_VulkanState.m_GraphicImageSemaphore[frameInfo.m_FrameIndex] ,
244 &frameInfo.m_ImageIndex
248
249
250 if (result == VK_ERROR_OUT_OF_DATE_KHR)
254 else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
256 SPICES_CORE_ERROR(
"Failed to acquire swap chain image!")
262 ThreadModel::Get()->GetGameThreadPool()->Suspend();
268 ThreadModel::Get()->GetRHIThreadPool()->FreeParallelCommandBuffers(frameInfo.m_FrameIndex);
282
283
284 VkCommandBufferBeginInfo beginInfo{};
285 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
286 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
287 beginInfo.pInheritanceInfo =
nullptr;
290
291
292 VK_CHECK(vkBeginCommandBuffer(m_VulkanState.m_ComputeCommandBuffer[frameInfo.m_FrameIndex], &beginInfo))
295
296
297 beginInfo.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
298 VK_CHECK(vkBeginCommandBuffer(m_VulkanState.m_GraphicCommandBuffer[frameInfo.m_FrameIndex], &beginInfo))
301
302
329
330
335
336
344 DEBUGUTILS_BEGINQUEUELABEL(
m_VulkanState.m_ComputeQueue,
"MainComputeQueue")
346 VkSemaphore waitSemphores[] = { m_VulkanState.m_GraphicImageSemaphore[frameInfo.m_FrameIndex] };
347 VkSemaphore signalSemaphores[] = { m_VulkanState.m_ComputeQueueSemaphore[frameInfo.m_FrameIndex] };
348 VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT };
351
352
353 VkSubmitInfo submitInfo{};
354 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
355 submitInfo.waitSemaphoreCount = 1;
356 submitInfo.pWaitSemaphores = waitSemphores;
357 submitInfo.pWaitDstStageMask = waitStages;
358 submitInfo.commandBufferCount = 1;
359 submitInfo.pCommandBuffers = &m_VulkanState.m_ComputeCommandBuffer[frameInfo.m_FrameIndex];
360 submitInfo.signalSemaphoreCount = 1;
361 submitInfo.pSignalSemaphores = signalSemaphores;
364
365
366 VK_CHECK(vkQueueSubmit(m_VulkanState.m_ComputeQueue, 1, &submitInfo, m_VulkanState.m_ComputeFence[frameInfo.m_FrameIndex]))
374 DEBUGUTILS_BEGINQUEUELABEL(
m_VulkanState.m_GraphicQueue,
"MainGraphicQueue")
376 VkSemaphore waitSemphores[] = { m_VulkanState.m_ComputeQueueSemaphore[frameInfo.m_FrameIndex] };
377 VkSemaphore signalSemaphores[] = { m_VulkanState.m_GraphicQueueSemaphore[frameInfo.m_FrameIndex] };
378 VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
381
382
383 VkSubmitInfo submitInfo{};
384 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
385 submitInfo.waitSemaphoreCount = 1;
386 submitInfo.pWaitSemaphores = waitSemphores;
387 submitInfo.pWaitDstStageMask = waitStages;
388 submitInfo.commandBufferCount = 1;
389 submitInfo.pCommandBuffers = &m_VulkanState.m_GraphicCommandBuffer[frameInfo.m_FrameIndex];
390 submitInfo.signalSemaphoreCount = 1;
391 submitInfo.pSignalSemaphores = signalSemaphores;
394
395
396 VK_CHECK(vkQueueSubmit(m_VulkanState.m_GraphicQueue, 1, &submitInfo, m_VulkanState.m_GraphicFence[frameInfo.m_FrameIndex]))
405 NSIGHTPERF_GPUPROFILERCONTINUOUS_ENDFRAME
406 NSIGHTPERF_GPUPROFILERREPORT_ENDFRAME(m_VulkanState)
407 NSIGHTPERF_GPUPROFILERONESHOT_ENDFRAME
413 DEBUGUTILS_BEGINQUEUELABEL(
m_VulkanState.m_PresentQueue,
"PresentQueue")
416
417
418 VkPresentInfoKHR presentInfo{};
419 presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
420 presentInfo.waitSemaphoreCount = 1;
421 presentInfo.pWaitSemaphores = &m_VulkanState.m_GraphicQueueSemaphore[frameInfo.m_FrameIndex];
422 presentInfo.swapchainCount = 1;
423 presentInfo.pSwapchains = &m_VulkanState.m_SwapChain;
424 presentInfo.pImageIndices = &frameInfo.m_ImageIndex;
425 presentInfo.pResults =
nullptr;
428
429
430 VkResult result = vkQueuePresentKHR(m_VulkanState.m_PresentQueue, &presentInfo);
431 if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || m_VulkanWindows->IsResized())
433 m_VulkanWindows->SetResized(
false);
436 else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
438 SPICES_CORE_ERROR(
"Failed to present swap chain image!")
447 ThreadModel::Get()->GetGameThreadPool()->Continue();
456
457
476 m_VulkanDevice->RequerySwapChainSupport();
479
480
481 m_VulkanSwapChain->Destroy();
482 m_VulkanSwapChain->Create();
485
486
490
491
500
501
502 m_RendererResourcePool->OnSlateResize(event.GetWidth(), event.GetHeight());
505
506
510
511
520
521
#define BIND_EVENT_FN(x)
Bind Event.
#define SPICES_PROFILE_GPU_CREATEINSTANCE(...)
#define SPICES_PROFILE_VK_DESTROY
#define SPICES_PROFILE_ZONEN(...)
#define SPICES_PROFILE_ZONE
#define VK_CHECK(expr)
Vulkan Check macro. Verify Vulkan API Effectiveness.
EventDispatcher(Event &event)
Constructor Function.
This Class store a Specific Event type first and Dispatch a event handle function to it.
static EventCallbackFn GetEventCallbackFn()
Get Global Root Event Function Pointer.
This Class is the basic Event Class. Inherit from it and create specific event class.
uint32_t m_FrameIndex
FrameIndex, varying during 0 - (MaxFrameInFlight - 1). Used almost anywhere.
FrameInfo Class. This class defines the FrameInfo data.
This Class is inherited from Event Class.
static void OnSlateResize()
Event Called on Slate resize.
static void OnWindowResizeOver()
This function is called on swapchain resized or out of data. Recreate all renderer render pass,...
static void Run(TimeStep &ts, FrameInfo &frameInfo)
All renderer Start to Render.
static RendererManager & Get()
Get Static RendererManager.
static RendererManager & Pop(const std::string &rendererName)
Pop a renderer from this manager, and destroy it.
static void OnMeshAddedWorld()
Event Called on world mark querier.
RendererManager Class. This class Manages all renderer.
RendererResourcePool Class. This class is a pool of all framebuffer's attachment.
This Class is inherited from Event Class. Called by Viewport Resize.
This Class handles our engine time step during frames. Global Unique.
VulkanDescriptorPool Class. This class is the wrapper of VkDescriptorPool.
void EndFrame(FrameInfo &frameInfo)
End record the frame with vulkan render backend.
void RecreateSwapChain()
Called OnSlateResize.
virtual ~VulkanRenderBackend()
Destructor Function.
VulkanRenderBackend()
Constructor Function.
static VulkanState m_VulkanState
The VulkanState in use.
static std::shared_ptr< VulkanDescriptorPool > m_VulkanDescriptorPool
The VulkanDescriptorPool in use.
static std::shared_ptr< RendererResourcePool > m_RendererResourcePool
The RendererResourcePool in use.
bool OnMeshAddedWorldEvent(WorldEvent &event)
This function is called on world mark query tick.
void RenderFrame(TimeStep &ts, FrameInfo &frameInfo)
Draw World.
void OnEvent(Event &event)
This function is called on global event function is called.
void BeginFrame(FrameInfo &frameInfo)
Start record a new frame with vulkan render backend.
bool OnWindowResizeOver(WindowResizeOverEvent &event)
This function is called on window is resized over.
bool OnSlateResize(SlateResizeEvent &event)
This function is called on viewport is resized.
This class defines the render backend behaves of Vulkan.
WindowResizeOverEvent(uint32_t width, uint32_t height)
Constructor Function.
This Class is inherited from Event Class. Inherit from it and create specific KeyEvent class....
const WindowInfo initInfo
Window create parameter.
uint32_t m_GraphicQueueFamily
This struct contains all Vulkan object in used global.
This struct defines the basic information of window.