Engine
Frameworkcreatedbymeusableforthecreationofsimplegames.CurrentlysupportsOpenGL(Verysimple)andVulkan.
VulkanRenderer.cpp
Go to the documentation of this file.
1 // Written by Koen Buitenhuis
2 
4 #ifdef USING_VULKAN
5 #define VMA_IMPLEMENTATION
8 #include "Engine/engine.hpp"
9 //#include <chrono>
10 //#include <stdexcept>
11 #include <cstring>
12 #include <thread>
13 //#include <fstream>
14 //#include <set>
15 #include <ThirdParty/glm/glm/gtc/matrix_transform.hpp>
18 #include <ThirdParty/EASTL-master/include/EASTL/shared_ptr.h>
19 
20 
21 namespace Engine
22 {
23 
24  static void check_vk_result(VkResult err) {
25  if (err != VK_SUCCESS) {
26  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(err).c_str() + "] ImGui vulkan call failed";
27  std::cout << s.c_str() << std::endl;
28  }
29  }
30 
31  VulkanRenderer::VulkanRenderer() noexcept
32  {
33  initialized = false;
34  setClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f));
35  }
36 
37  VulkanRenderer::~VulkanRenderer()
38  {
39  vkWaitForFences(vulkanLogicalDevice_->GetDevice(),
40  static_cast<uint32_t>(drawingFinishedFences_.size()),
41  drawingFinishedFences_.data(),
42  VK_TRUE, eastl::numeric_limits<uint64_t>::max());
43 
44  vkDeviceWaitIdle(vulkanLogicalDevice_->GetDevice());
45 
46  vkResetCommandPool(vulkanLogicalDevice_->GetDevice(), graphicsCommandPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
47  vkResetCommandPool(vulkanLogicalDevice_->GetDevice(), computeCommandPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
48 
49  vkDeviceWaitIdle(vulkanLogicalDevice_->GetDevice());
50 
51  DestroyThreads();
52  DestroyRenderers();
53  DestroyGBufferRenderPipeline();
54  DestroyCompositingPipeline();
55  DestroySemaphores();
56  DestroyImGui();
57  DestroyDecriptorPool();
58  DestroyFramebuffers();
59  DestroyRenderPass();
60  DestroyAttachmentImages();
61  DestroyDepthImage();
62  DestroyVmaAllocator();
63  DestroyGraphicsCommandPool();
64  DestroyComputeCommandPool();
65  DestroySwapChainImageViews();
66  DestroySwapChain();
67  DestroyLogicalDevice();
68  DestroyInstance();
69  }
70 
71  void VulkanRenderer::InitializeRenderer()
72  {
73  InitializeRenderer(Engine::GetEngine().lock()->GetWindow<VulkanWindow>());
74  }
75 
76  void VulkanRenderer::InitializeRenderer(eastl::weak_ptr<VulkanWindow> window)
77  {
78  if (initialized)
79  return;
80 
81  this->window = window;
82 
83  swapChain = VK_NULL_HANDLE;
84 
85  CreateInstance();
86 
87  surface = window.lock()->CreateSurface(vulkanInstance_->GetInstance());
88 
89  FindPhysicalDevice();
90 
91  CreateLogicalDevice();
92 
93  CreateSwapChain();
94 
95  GetSwapChainImages();
96  CreateSwapChainImageViews();
97 
98  CreateGraphicsCommandPool();
99  CreateComputeCommandPool();
100 
101  CreateVmaAllocator();
102 
103  CreateDepthImage();
104 
105  CreateAttachmentImages();
106 
107  CreateRenderPass();
108 
109  CreateFramebuffers();
110 
111  CreateDescriptorPool();
112 
113  InitImGui();
114 
115  CreateSemaphores();
116 
117  CreateCompositingPipeline();
118 
119  CreateGBufferRenderPipeline();
120 
121  GenerateCommandBuffers();
122 
123  AllocateThreads();
124 
125  activeLights = 0;
126 
127  currentImage = 0;
128 
129  VulkanTexture::InitTextureSystem(this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get(), vmaAllocator_, graphicsCommandPool);
130 
131  VulkanMesh::InitMeshes(this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get(), graphicsCommandPool);
132 
133  VulkanMaterial::InitMaterialData(this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get(), vmaAllocator_);
134 
135  CreateRenderers();
136 
137  /*Engine::GetEngine().lock()->GetResourceManager().lock()->CreateSkeleton("xbot.fbx");
138  Engine::GetEngine().lock()->GetResourceManager().lock()->CreateModel("test", "xbot.fbx");
139  Engine::GetEngine().lock()->GetResourceManager().lock()->AddAnimationsToSkeleton("xbot.fbx", "Standard Walk.fbx");
140  Engine::GetEngine().lock()->GetResourceManager().lock()->GetModel("test")->SetAnimation(
141  Engine::GetEngine().lock()->GetResourceManager().lock()->
142  GetModel("test")->GetAnimations()[0], true);
143  Engine::GetEngine().lock()->GetResourceManager().lock()->GetModel("test")->SetPaused(false);
144  Engine::GetEngine().lock()->GetResourceManager().lock()->GetModel("test")->SetLooping(true);*/
145  /*
146  CreateLight("spot1", LightType::LIGHT_SPOT_LIGHT,
147  glm::vec3(0.f,40.f,25.f), glm::normalize(glm::vec3(-0.25f, -0.75f, 0.5f)),
148  glm::vec3(0.25f, 1.f, 0.25f), 800.f, 0.f, 1.f/10.f*glm::pi<float>(), 1.f/3.f*glm::pi<float>());*/
149  /*
150  CreateLight("dir1", LightType::LIGHT_DIRECTIONAL_LIGHT,
151  glm::vec3(0.f), glm::normalize(glm::vec3(0.75f, -0.9f, 1.f)),
152  glm::vec3(0.75f, 0.75f, 0.75f), 0.f, 0.f, 0.f, 0.f);*/
153 
154  //CreateLight("dir1", LightType::LIGHT_DIRECTIONAL_LIGHT,
155  // glm::vec3(25.f, 25.f, 10.f), glm::vec3(0.25f,0.25f,0.5f),
156  // glm::vec3(0.8f, 0.8f, 0.8f), 800.f, 0.f, glm::radians<float>(30.f), glm::radians<float>(70.f));
157 
158 
159  //CreateLight("amb1", LightType::LIGHT_AMBIENT_LIGHT,
160  // glm::vec3(25.f, 25.f, 10.f), glm::vec3(0.25f, 0.25f, 0.5f),
161  // glm::vec3(0.2f, 0.2f, 0.2f), 800.f, 0.f, glm::radians<float>(30.f), glm::radians<float>(70.f));
162  /*
163  CreateLight("point1", LightType::LIGHT_SPOT_LIGHT,
164  glm::vec3(25.f, 25.f, 10.f), glm::vec3(-0.25f, -0.25f, 0.5f),
165  glm::vec3(0.8f, 0.8f, 0.8f), 800.f, 0.f, glm::radians<float>(30.f), glm::radians<float>(70.f));*/
166 
167  firstRender = true;
168 
169  initialized = true;
170 
171  resized = false;
172  }
173 
174  void VulkanRenderer::Resized()
175  {
176  resized = true;
177  }
178 
179  void VulkanRenderer::RecreateSwapChain()
180  {
181  vkDeviceWaitIdle(vulkanLogicalDevice_->GetDevice());
182 
183  DestroyFramebuffers();
184 
185  DestroyCompositingPipeline();
186  DestroyGBufferRenderPipeline();
187  vulkanSpriteRenderer->Clean();
188  vulkanDebugRenderer->Clean();
189  vulkanStaticMeshRenderer->Clean();
190  vulkanSkeletalMeshRenderer->Clean();
191 
192  DestroyImGui();
193 
194  DestroyRenderPass();
195  DestroyAttachmentImages();
196  DestroyDepthImage();
197  DestroySwapChainImageViews();
198  DestroySwapChain();
199 
200  CreateSwapChain();
201  GetSwapChainImages();
202  CreateSwapChainImageViews();
203  CreateDepthImage();
204  CreateAttachmentImages();
205  CreateRenderPass();
206  CreateFramebuffers();
207 
208  CreateCompositingPipeline();
209  CreateGBufferRenderPipeline();
210 
211  vulkanSpriteRenderer->Recreate();
212  vulkanDebugRenderer->Recreate();
213  vulkanStaticMeshRenderer->Recreate();
214  vulkanSkeletalMeshRenderer->Recreate();
215 
216  InitImGui();
217 
218  GenerateCommandBuffers();
219 
220  resized = false;
221 
222  }
223 
224  void VulkanRenderer::setClearColor(glm::vec4 color)
225  {
226  clearValue.color = { color.x,color.y,color.z,color.w };
227  }
228 
229  VkRenderPass VulkanRenderer::GetRenderPass() const
230  {
231  return renderPass;
232  }
233 
234  VkRenderPass VulkanRenderer::GetGBufferRenderPass() const
235  {
236  return gBufferPass;
237  }
238 
239  VmaAllocator VulkanRenderer::GetVmaAllocator() const
240  {
241  return vmaAllocator_;
242  }
243 
244  VkCommandPool VulkanRenderer::GetGraphicsCommandPool() const
245  {
246  return graphicsCommandPool;
247  }
248 
249  VkCommandPool VulkanRenderer::GetComputeCommandPool() const
250  {
251  return computeCommandPool;
252  }
253 
254  VkExtent2D VulkanRenderer::GetSwapChainExtent() const
255  {
256  return swapChainImageExtent;
257  }
258 
259  void VulkanRenderer::RendererBegin()
260  {
261  RendererBegin(glm::mat4(), glm::perspective(75.f,
262  static_cast<float>(swapChainImageExtent.width) / static_cast<float>(swapChainImageExtent.height),
263  0.1f, 1000.f));
264  }
265 
266  void VulkanRenderer::RendererBegin(const glm::mat4x4 & view, const glm::mat4x4 & projection)
267  {
268  //vkDeviceWaitIdle(vulkanLogicalDevice->GetDevice());
269  uint32_t imageIndex;
270  VkResult res = vkAcquireNextImageKHR(vulkanLogicalDevice_->GetDevice(), swapChain, eastl::numeric_limits<uint64_t>::max(), imageAvailableSemaphores_[(currentImage + 1) % imageAvailableSemaphores_.size()], VK_NULL_HANDLE, &imageIndex);
271 
272  if (res == VK_ERROR_OUT_OF_DATE_KHR) {
273  RecreateSwapChain();
274  }
275  else if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) {
276  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to aquire next swap chain image";
277  std::cout << s.c_str() << std::endl;
278  return;
279  }
280 
281  currentBuffer_ = primaryRenderCommandBuffers_[imageIndex];
282  currentComputeBuffer_ = primaryComputeCommandBuffers_[imageIndex];
283  this->prevImage = this->currentImage;
284  this->currentImage = imageIndex;
285 
286  //vkQueueWaitIdle(vulkanLogicalDevice_->GetComputeQueue());
287  VkFence fences[] = { drawingFinishedFences_[currentImage], computeFinishedFences_[currentImage] };
288  vkWaitForFences(vulkanLogicalDevice_->GetDevice(), 2, fences, true, eastl::numeric_limits<uint64_t>::max());
289  vkResetFences(vulkanLogicalDevice_->GetDevice(), 2, fences);
290 
291  /*VkResult res = vkQueueWaitIdle(vulkanLogicalDevice->GetGraphicsQueue());
292  if (res != VK_SUCCESS) {
293  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Queue wait idle failed";
294  std::cout << s.c_str() << std::endl;
295  }*/
296 
297  if (resized) {
298  VkResult res = vkQueueWaitIdle(vulkanLogicalDevice_->GetGraphicsQueue());
299  if (res != VK_SUCCESS) {
300  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Queue wait idle failed";
301  std::cout << s.c_str() << std::endl;
302  }
303  RecreateSwapChain();
304  }
305 
306  ImGui_ImplGlfwVulkan_NewFrame();
307 
308 
309  vulkanSpriteRenderer->StartRender(spriteRenderCommandBuffers_[imageIndex], view, projection);
310  vulkanDebugRenderer->StartRender(debugRenderCommandBuffers_[imageIndex], view, projection);
311  vulkanStaticMeshRenderer->StartRender(view, projection);
312  vulkanSkeletalMeshRenderer->StartRender(view, projection);
313 
314  glm::vec3 camPos = Engine::GetEngine().lock()->GetCamera().lock()->GetPosition();
315  scene.viewPos = glm::vec4(camPos.x, camPos.y, camPos.z, 1.f);
316  /*
317  Engine::GetEngine().lock()->GetResourceManager().lock()->GetModel("test")->UpdateAnimation(
318  Engine::GetEngine().lock()->GetTime().lock()->GetDeltaTime());
319 
320  Render(glm::translate(glm::mat4(), glm::vec3(-50.f, -200.f, -150.f)), Engine::GetEngine().lock()->GetResourceManager().lock()->GetModel("test"));
321  Render(glm::translate(glm::mat4(), glm::vec3(50.f, -200.f, -150.f)), Engine::GetEngine().lock()->GetResourceManager().lock()->GetModel("test"));*/
322 
323  //RenderSprite(texture, glm::translate(glm::mat4(), glm::vec3(0.f, 0.f, -1.f))*glm::scale(glm::mat4(),glm::vec3(64.f,64.f,1.f)));
324  //RenderSprite(texture, glm::translate(glm::mat4(), glm::vec3(40.f, 0.f, -40.f))*glm::scale(glm::mat4(), glm::vec3(64.f, 64.f, 1.f)));
325 
326  //RenderSprite(texture, glm::mat4());
327  }
328 
330  {
331 
332  }
333 
334  void VulkanRenderer::Render(const glm::mat4x4 & modelMatrix, eastl::shared_ptr<Model> model, const glm::vec4 & mainColor)
335  {
336  eastl::vector<eastl::shared_ptr<Mesh>> meshes = model->GetModelMeshes();
337 
338  for (size_t i = 0, size = meshes.size(); i < size; i++) {
339  if (meshes[i] == nullptr)
340  {
341  continue;
342  }
343 
344  eastl::shared_ptr<VulkanMaterial> material =
345  eastl::dynamic_pointer_cast<VulkanMaterial, Material>(model->GetMeshMaterial(meshes[i]));
346 
347  bool isAnimated = eastl::dynamic_pointer_cast<VulkanMesh, Mesh>(meshes[i])->IsAnimated();
348  size_t currentAnimationIndex = model->GetCurrentAnimationIndex();
349 
350  if (!isAnimated ||
351  currentAnimationIndex == -1 ||
352  model->GetSkeleton() == nullptr) {
353  vulkanStaticMeshRenderer->RenderMesh(modelMatrix,
354  eastl::dynamic_pointer_cast<VulkanMesh, Mesh>(meshes[i]), material, mainColor);
355  }
356  else {
357  vulkanSkeletalMeshRenderer->RenderMesh(modelMatrix,
358  static_cast<VulkanMesh*>(meshes[i].get()),
359  material.get(), model->GetSkeleton().get(), model->GetCurrentAnimationIndex(), model->GetAnimationTime(),
360  model->GetSkeleton()->GetAnimationTicksPerSecond(model->GetCurrentAnimationIndex()),
361  model->GetAnimationDuration(), model->IsLooping(), mainColor);
362  }
363  }
364  }
365 
366  void VulkanRenderer::RenderSprite(eastl::weak_ptr<Texture> texture, glm::mat4 modelMatrix)
367  {
368  eastl::weak_ptr<VulkanTexture> vulkanTexture;
369 
370  vulkanTexture = eastl::dynamic_pointer_cast<VulkanTexture, Texture>(texture.lock());
371 
372  vulkanSpriteRenderer->RenderSprite(vulkanTexture, modelMatrix);
373  }
374 
375  void VulkanRenderer::RenderLine(glm::vec3 start, glm::vec3 end, glm::vec4 color)
376  {
377  vulkanDebugRenderer->RenderLine(start, end, color);
378  }
379 
380  void VulkanRenderer::RendererEnd()
381  {
382  VkCommandBufferBeginInfo beginInfo = {};
383  beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
384  beginInfo.pInheritanceInfo = nullptr;
385  //beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
386 
387  vkBeginCommandBuffer(currentComputeBuffer_, &beginInfo);
388 
389  // TODO - add compute stuff
390 
391  vkEndCommandBuffer(currentComputeBuffer_);
392 
393  VkSubmitInfo computeSubmitInfo = {};
394  computeSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
395 
396  computeSubmitInfo.waitSemaphoreCount = 0;
397  computeSubmitInfo.pWaitSemaphores = nullptr;
398  computeSubmitInfo.pWaitDstStageMask = nullptr;
399  computeSubmitInfo.commandBufferCount = 1;
400  computeSubmitInfo.pCommandBuffers = &currentComputeBuffer_;
401  computeSubmitInfo.signalSemaphoreCount = 1;
402  VkSemaphore computeSignalSemaphores[] = { computeFinishedSemaphores_[currentImage] };
403  computeSubmitInfo.pSignalSemaphores = computeSignalSemaphores;
404 
405  VkResult res = vkQueueSubmit(vulkanLogicalDevice_->GetComputeQueue(), 1, &computeSubmitInfo, computeFinishedFences_[currentImage]);
406  if (res != VK_SUCCESS) {
407  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to submit compute commands";
408  std::cout << s.c_str() << std::endl;
409  }
410 
411  beginInfo = {};
412  beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
413  beginInfo.pInheritanceInfo = nullptr;
414  //beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
415 
416  vkBeginCommandBuffer(currentBuffer_, &beginInfo);
417 
418  eastl::array<VkClearValue, static_cast<int>(GBufferAttachments::ATTACHMENT_COUNT)> gbufferClearValues = {};
419  gbufferClearValues[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].color = clearValue.color;
420  gbufferClearValues[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].color = { 0.f,0.f,0.f,0.f };
421  gbufferClearValues[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].color = { 0.f,0.f,0.f,0.f };
422  gbufferClearValues[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].depthStencil = { 1.0f,0 };
423 
424  VkRenderPassBeginInfo renderPassInfo = {};
425  renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
426  renderPassInfo.renderPass = gBufferPass;
427  renderPassInfo.framebuffer = gBufferFrameBuffer;
428  renderPassInfo.renderArea.offset = { 0,0 };
429  renderPassInfo.renderArea.extent = swapChainImageExtent;
430  renderPassInfo.clearValueCount = static_cast<uint32_t>(gbufferClearValues.size());
431  renderPassInfo.pClearValues = gbufferClearValues.data();
432 
433  vkCmdBeginRenderPass(currentBuffer_, &renderPassInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
434 
435  /*ThreadInfo* freeThread = GetFreeThread();
436  if (freeThread != nullptr) {
437  freeThread->task = std::packaged_task<void()>(std::bind(&VulkanStaticMeshRenderer::FinishRender, vulkanStaticMeshRenderer.get(),
438  freeThread->threadId, freeThread->commandPool, &(staticMeshCommandBuffers_[currentImage])));
439  freeThread->future = freeThread->task.get_future();
440  freeThread->thread = std::thread(std::move(freeThread->task));
441  freeThread->initialized = true;
442  }
443  else {*/
444  vulkanStaticMeshRenderer->FinishRender(0, graphicsCommandPool, (staticMeshCommandBuffers_[currentImage]));
445  //}
446  /*freeThread = GetFreeThread();
447  if (freeThread != nullptr) {
448  freeThread->task = std::packaged_task<void()>(std::bind(&VulkanSkeletalMeshRenderer::FinishRender, vulkanSkeletalMeshRenderer.get(),
449  freeThread->threadId, freeThread->commandPool, &(skeletalMeshCommandBuffers_[currentImage])));
450  freeThread->future = freeThread->task.get_future();
451  freeThread->thread = std::thread(std::move(freeThread->task));
452  freeThread->initialized = true;
453  }
454  else {*/
455  vulkanSkeletalMeshRenderer->FinishRender(0, graphicsCommandPool, (skeletalMeshCommandBuffers_[currentImage]));
456  //}
457 
458  vkCmdExecuteCommands(currentBuffer_, 1, &staticMeshCommandBuffers_[currentImage]);
459 
460  vkCmdExecuteCommands(currentBuffer_, 1, &skeletalMeshCommandBuffers_[currentImage]);
461 
462  vkCmdEndRenderPass(currentBuffer_);
463 
464  eastl::array<VkClearValue, static_cast<int>(RenderPassAttachments::ATTACHMENT_COUNT)> renderClearValues = {};
465  renderClearValues[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].color = clearValue.color;
466  renderClearValues[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].color = { 0.f,0.f,0.f,0.f };
467  //clearValues[SubPasses::RENDER_PASS].depthStencil = { 1.f,0 };
468  renderClearValues[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].color = clearValue.color;
469  //clearValues[SubPasses::IMGUI_PASS].depthStencil = { 1.f,0 };
470  renderClearValues[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].color = clearValue.color;
471 
472  renderPassInfo = {};
473  renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
474  renderPassInfo.renderPass = renderPass;
475  renderPassInfo.framebuffer = framebuffers[currentImage];
476  renderPassInfo.renderArea.offset = { 0,0 };
477  renderPassInfo.renderArea.extent = swapChainImageExtent;
478  renderPassInfo.clearValueCount = static_cast<uint32_t>(renderClearValues.size());
479  renderPassInfo.pClearValues = renderClearValues.data();
480 
481  vkCmdBeginRenderPass(currentBuffer_, &renderPassInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
482 
483  StartSecondaryCommandBufferRecording(imguiCommandBuffers_[currentImage],
484  VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
485  renderPass, static_cast<int>(RenderSubPasses::IMGUI_PASS), framebuffers[currentImage]);
486 
487  ImGui_ImplGlfwVulkan_Render(imguiCommandBuffers_[currentImage]);
488  EndSecondaryCommandBufferRecording(imguiCommandBuffers_[currentImage]);
489 
490  vulkanSpriteRenderer->FinishRender();
491  vulkanDebugRenderer->FinishRender();
492 
493  if (lightDataRestructured)
494  RestructureLights();
495  if (lightDataChanged)
496  UpdateLightData();
497 
498  scene.lightCount = activeLights;
499  sceneDataBuffer->UpdateBuffer(&scene, 0, static_cast<uint32_t>(sizeof(scene)));
500 
501  uint32_t size = static_cast<uint32_t>(staticMeshShadowCommandBuffers_[currentImage].size());
502 
503  if (size < static_cast<uint32_t>(activeLights)) {
504  staticMeshShadowCommandBuffers_[currentImage].resize(activeLights);
505  GenerateSecondaryCommandBuffers(staticMeshShadowCommandBuffers_[currentImage].data() + sizeof(VkCommandBuffer)*size,
506  static_cast<uint32_t>(staticMeshShadowCommandBuffers_[currentImage].size()) - size);
507  }
508 
509  size = static_cast<uint32_t>(skeletalMeshShadowCommandBuffers_[currentImage].size());
510 
511  if (size < static_cast<uint32_t>(activeLights)) {
512  skeletalMeshShadowCommandBuffers_[currentImage].resize(activeLights);
513  GenerateSecondaryCommandBuffers(skeletalMeshShadowCommandBuffers_[currentImage].data() + sizeof(VkCommandBuffer)*size,
514  static_cast<uint32_t>(skeletalMeshShadowCommandBuffers_[currentImage].size()) - size);
515  }
516 
517  size = static_cast<uint32_t>(gBufferShadowCommandBuffers_[currentImage].size());
518 
519  if (size < static_cast<uint32_t>(activeLights)) {
520  gBufferShadowCommandBuffers_[currentImage].resize(activeLights);
521  GenerateSecondaryCommandBuffers(gBufferShadowCommandBuffers_[currentImage].data() + sizeof(VkCommandBuffer)*size,
522  static_cast<uint32_t>(gBufferShadowCommandBuffers_[currentImage].size()) - size);
523  }
524 
525 
526  VkRect2D scissor = { 0,0,swapChainImageExtent };
527  VkViewport viewport = { 0.f,0.f,static_cast<float>(swapChainImageExtent.width),static_cast<float>(swapChainImageExtent.height),-1.f,1.f };
528 
529  VkDescriptorSet sceneDescriptorSet = GetLightDescriptorSet(0, gBufferRenderPipeline_->GetPipelineId(), 1);
530  if (sceneDescriptorSet == VK_NULL_HANDLE) {
531  sceneDescriptorSet = CreateLightDescriptorSet(0, gBufferRenderPipeline_->GetPipelineId(), 1, gBufferRenderPipeline_->GetDescriptorSetLayout(1));
532  }
533 
534  for (int i = 0; i < activeLights; ++i) {
535  if (!(lightData[i].position.w == 0.f && lightData[i].direction == glm::vec4(0.f))) {
536  /*freeThread = GetFreeThread();
537  if (freeThread != nullptr) {
538  freeThread->task = std::packaged_task<void()>(std::bind(&VulkanStaticMeshRenderer::RenderShadows, vulkanStaticMeshRenderer.get(),
539  freeThread->threadId, freeThread->commandPool,
540  &(staticMeshShadowCommandBuffers_[currentImage][i]), static_cast<uint32_t>(i * sizeof(Light))));
541  freeThread->future = freeThread->task.get_future();
542  freeThread->thread = std::thread(std::move(freeThread->task));
543  freeThread->initialized = true;
544  }
545  else {*/
546  vulkanStaticMeshRenderer->RenderShadows(0, graphicsCommandPool, (staticMeshShadowCommandBuffers_[currentImage][i]), static_cast<uint32_t>(i * sizeof(Light)));
547  //}
548  /*freeThread = GetFreeThread();
549  if (freeThread != nullptr) {
550  freeThread->task = std::packaged_task<void()>(std::bind(&VulkanSkeletalMeshRenderer::RenderShadows, vulkanSkeletalMeshRenderer.get(),
551  freeThread->threadId, freeThread->commandPool,
552  &(skeletalMeshShadowCommandBuffers_[currentImage][i]), static_cast<uint32_t>(i * sizeof(Light))));
553  freeThread->future = freeThread->task.get_future();
554  freeThread->thread = std::thread(std::move(freeThread->task));
555  freeThread->initialized = true;
556  }
557  else {*/
558  vulkanSkeletalMeshRenderer->RenderShadows(0, graphicsCommandPool, (skeletalMeshShadowCommandBuffers_[currentImage][i]), static_cast<uint32_t>(i * sizeof(Light)));
559  //}
560  }
561  StartSecondaryCommandBufferRecording(gBufferShadowCommandBuffers_[currentImage][i],
562  VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
563  renderPass, static_cast<int>(RenderSubPasses::RENDER_PASS), framebuffers[currentImage]);
564 
565  vkCmdBindPipeline(gBufferShadowCommandBuffers_[currentImage][i], VK_PIPELINE_BIND_POINT_GRAPHICS, gBufferRenderPipeline_->GetPipeline());
566 
567  vkCmdSetScissor(gBufferShadowCommandBuffers_[currentImage][i], 0, 1, &scissor);
568 
569  VkDescriptorSet descriptors[] = { gBufferAttachmentDescriptorSet_ };
570 
571  vkCmdBindDescriptorSets(gBufferShadowCommandBuffers_[currentImage][i],
572  VK_PIPELINE_BIND_POINT_GRAPHICS,
573  gBufferRenderPipeline_->GetPipelineLayout(),
574  0, 1,
575  descriptors,
576  0, nullptr);
577 
578  uint32_t dynamicOffset[] = { static_cast<uint32_t>(i * sizeof(Light)) };
579 
580  vkCmdBindDescriptorSets(gBufferShadowCommandBuffers_[currentImage][i],
581  VK_PIPELINE_BIND_POINT_GRAPHICS,
582  gBufferRenderPipeline_->GetPipelineLayout(),
583  1, 1,
584  &sceneDescriptorSet,
585  1, dynamicOffset);
586 
587 
588  VkDeviceSize offsets[] = { 0 };
589 
590  vkCmdBindVertexBuffers(gBufferShadowCommandBuffers_[currentImage][i], 0, 1, &vertexBuffer_, offsets);
591 
592  vkCmdDraw(gBufferShadowCommandBuffers_[currentImage][i], 6, 1, 0, 0);
593 
594  EndSecondaryCommandBufferRecording(gBufferShadowCommandBuffers_[currentImage][i]);
595  }
596 
597  StartSecondaryCommandBufferRecording(clearStencilCommandBuffers_[currentImage],
598  VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
599  renderPass, static_cast<int>(RenderSubPasses::RENDER_PASS), framebuffers[currentImage]);
600 
601  VkClearValue clearValue = {};
602  clearValue.depthStencil = { 0.f,0 };
603 
604  VkClearAttachment stencilAttachment = {};
605  stencilAttachment.colorAttachment = static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT);
606  stencilAttachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
607  stencilAttachment.clearValue = clearValue;
608 
609  VkClearRect clearRect = {};
610  clearRect.baseArrayLayer = 0;
611  clearRect.layerCount = 1;
612  clearRect.rect.offset = { 0,0 };
613  clearRect.rect.extent = swapChainImageExtent;
614 
615  vkCmdClearAttachments(clearStencilCommandBuffers_[currentImage], 1, &stencilAttachment, 1, &clearRect);
616 
617  EndSecondaryCommandBufferRecording(clearStencilCommandBuffers_[currentImage]);
618 
619  JoinAllThreads();
620 
621  vkCmdNextSubpass(currentBuffer_, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
622 
623  vkCmdExecuteCommands(currentBuffer_, 1, &spriteRenderCommandBuffers_[currentImage]);
624 
625  vkCmdExecuteCommands(currentBuffer_, 1, &debugRenderCommandBuffers_[currentImage]);
626 
627  for (int i = 0; i < activeLights; ++i) {
628  vkCmdExecuteCommands(currentBuffer_, 1, &(clearStencilCommandBuffers_[currentImage]));
629 
630  if (!(lightData[i].position.w == 0.f && lightData[i].direction == glm::vec4(0.f))) {
631  vkCmdExecuteCommands(currentBuffer_, 1, &(staticMeshShadowCommandBuffers_[currentImage][i]));
632  vkCmdExecuteCommands(currentBuffer_, 1, &(skeletalMeshShadowCommandBuffers_[currentImage][i]));
633  }
634  vkCmdExecuteCommands(currentBuffer_, 1, &(gBufferShadowCommandBuffers_[currentImage][i]));
635  }
636 
637  vkCmdNextSubpass(currentBuffer_, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
638 
639  vkCmdExecuteCommands(currentBuffer_, 1, &imguiCommandBuffers_[currentImage]);
640 
641  vkCmdNextSubpass(currentBuffer_, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
642 
643  vkCmdExecuteCommands(currentBuffer_, 1, &compositeCommandBuffer_);
644 
645  vkCmdEndRenderPass(currentBuffer_);
646 
647  res = vkEndCommandBuffer(currentBuffer_);
648  if (res != VK_SUCCESS) {
649  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to record primary command buffer";
650  std::cout << s.c_str() << std::endl;
651  return;
652  }
653 
654  VkSubmitInfo submitInfo = {};
655  submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
656  VkSemaphore waitSemaphores[] = {
657  imageAvailableSemaphores_[(prevImage + 1) % imageAvailableSemaphores_.size()],
658  computeFinishedSemaphores_[currentImage] };
659  VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT };
660  submitInfo.waitSemaphoreCount = 2;
661  submitInfo.pWaitSemaphores = waitSemaphores;
662  submitInfo.pWaitDstStageMask = waitStages;
663  submitInfo.commandBufferCount = 1;
664  submitInfo.pCommandBuffers = &currentBuffer_;
665  VkSemaphore signalSemaphors[] = { renderFinishedSemaphores_[currentImage] };
666  submitInfo.signalSemaphoreCount = 1;
667  submitInfo.pSignalSemaphores = signalSemaphors;
668 
669  res = vkQueueSubmit(vulkanLogicalDevice_->GetGraphicsQueue(), 1, &submitInfo, drawingFinishedFences_[currentImage]);
670  if (res != VK_SUCCESS) {
671  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Submitting command buffer to queue failed";
672  std::cout << s.c_str() << std::endl;
673  return;
674  }
675 
676  VkPresentInfoKHR presentInfo = {};
677  presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
678  presentInfo.waitSemaphoreCount = 1;
679  presentInfo.pWaitSemaphores = signalSemaphors;
680 
681  VkSwapchainKHR swapChains[] = { swapChain };
682  presentInfo.swapchainCount = 1;
683  presentInfo.pSwapchains = swapChains;
684  presentInfo.pImageIndices = &currentImage;
685  presentInfo.pResults = nullptr;
686 
687  res = vkQueuePresentKHR(vulkanLogicalDevice_->GetPresentQueue(), &presentInfo);
688  if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR) {
689  RecreateSwapChain();
690  }
691  else if (res != VK_SUCCESS) {
692  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to present swap chain image";
693  std::cout << s.c_str() << std::endl;
694  }
695 
696  if (firstRender)
697  firstRender = false;
698 
699 
700  }
701 
702  void VulkanRenderer::CreateLight(eastl::string name, LightType lightType,
703  glm::vec3 position, glm::vec3 direction, glm::vec3 color,
704  float radius, float attunuation, float coneInnerAngle, float coneOuterAngle)
705  {
706  LightInfo info = {};
707  info.active = true;
708  info.name = name;
709  info.type = lightType;
710 
711  switch (lightType) {
713  info.light.position = glm::vec4(position.x, position.y, position.z, 0.f);
714  info.light.direction = glm::vec4(0.f);
715  info.light.color = glm::vec4(color.x, color.y, color.z, 1.f);
716  info.light.radius = radius;
717  info.light.attunuation = attunuation;
718  info.light.coneInnerAngle = coneInnerAngle;
719  info.light.coneOuterAngle = coneOuterAngle;
720  break;
722  info.light.position = glm::vec4(position.x, position.y, position.z, 0.f);
723  info.light.direction = glm::vec4(-direction.x, -direction.y, direction.z, 0.f);
724  info.light.color = glm::vec4(color.x, color.y, color.z, 1.f);
725  info.light.radius = radius;
726  info.light.attunuation = attunuation;
727  info.light.coneInnerAngle = coneInnerAngle;
728  info.light.coneOuterAngle = coneOuterAngle;
729  break;
731  info.light.position = glm::vec4(position.x, position.y, position.z, 1.f);
732  info.light.direction = glm::vec4(-direction.x, -direction.y, direction.z, 0.f);
733  info.light.color = glm::vec4(color.x, color.y, color.z, 1.f);
734  info.light.radius = radius;
735  info.light.attunuation = attunuation;
736  info.light.coneInnerAngle = 2.f*glm::pi<float>();
737  info.light.coneOuterAngle = 2.f*glm::pi<float>();
738  break;
740  info.light.position = glm::vec4(position.x, position.y, position.z, 1.f);
741  info.light.direction = glm::vec4(-direction.x, -direction.y, direction.z, 0.f);
742  info.light.color = glm::vec4(color.x, color.y, color.z, 1.f);
743  info.light.radius = radius;
744  info.light.attunuation = attunuation;
745  info.light.coneInnerAngle = coneInnerAngle;
746  info.light.coneOuterAngle = coneOuterAngle;
747  break;
748  }
749 
750  lights[name] = info;
751 
752  lightDataRestructured = true;
753 
754  scene.lightCount = activeLights;
755  }
756 
757  void VulkanRenderer::SetLightType(eastl::string name, LightType lightType)
758  {
759  eastl::map<eastl::string, LightInfo>::iterator it = lights.find(name);
760 
761  if (it == lights.end())
762  return;
763 
764  LightInfo info = it->second;
765 
766  if (info.type == lightType)
767  return;
768 
769  if (info.type == LightType::LIGHT_NONEXISTENT) {
770  info.type = lightType;
771  info.active = true;
772  lightDataRestructured = true;
773  }
774 
775  if (lightType == LightType::LIGHT_NONEXISTENT) {
776  info.type = lightType;
777  info.active = false;
778  lightDataRestructured = true;
779  lights[name] = info;
780  }
781 
782  info.type = lightType;
783 
784  switch (lightType) {
786  info.light.position.w = 0.f;
787  info.light.direction = glm::vec4(0.f);
788  break;
790  info.light.position.w = 0.f;
791  break;
793  info.light.position.w = 1.f;
794  info.light.coneInnerAngle = 2.f * glm::pi<float>();
795  info.light.coneOuterAngle = 2.f * glm::pi<float>();
796  break;
798  info.light.position.w = 1.f;
799  info.light.coneInnerAngle = 0.f;
800  info.light.coneOuterAngle = 0.f;
801  break;
802  }
803 
804  lights[name] = info;
805 
806  if (lightDataRestructured == false)
807  lightData[info.lightDataIndex] = info.light;
808 
809  lightDataChanged = true;
810  }
811 
812  LightType VulkanRenderer::GetLightType(eastl::string name)
813  {
814  if (lights.count(name) > 0)
815  return lights[name].type;
816  else
817  return LightType::LIGHT_NONEXISTENT;
818  }
819 
820  void VulkanRenderer::SetLightPosition(eastl::string name, glm::vec3 position)
821  {
822  if (lights.count(name) <= 0)
823  return;
824 
825  LightInfo info = lights[name];
826 
827  info.light.position.x = position.x;
828  info.light.position.y = position.y;
829  info.light.position.z = position.z;
830 
831  if (info.active && (info.type == LightType::LIGHT_POINT_LIGHT || info.type == LightType::LIGHT_SPOT_LIGHT)) {
832  lightData[info.lightDataIndex] = info.light;
833  lightDataChanged = true;
834  }
835 
836  lights[name] = info;
837  }
838 
839  glm::vec3 VulkanRenderer::GetLightPosition(eastl::string name)
840  {
841  if (lights.count(name) <= 0)
842  return glm::vec3(0.f);
843 
844  LightInfo info = lights[name];
845 
846  return glm::vec3(info.light.position.x, info.light.position.y, info.light.position.z);
847  }
848 
849  void VulkanRenderer::SetLightDirection(eastl::string name, glm::vec3 direction)
850  {
851  if (lights.count(name) <= 0)
852  return;
853 
854  LightInfo info = lights[name];
855 
856 
857  if (info.active && (info.type == LightType::LIGHT_DIRECTIONAL_LIGHT || info.type == LightType::LIGHT_SPOT_LIGHT)) {
858  info.light.direction.x = -direction.x;
859  info.light.direction.y = -direction.y;
860  info.light.direction.z = direction.z;
861 
862  lightData[info.lightDataIndex] = info.light;
863  lightDataChanged = true;
864  }
865 
866  lights[name] = info;
867  }
868 
869  glm::vec3 VulkanRenderer::GetLightDirection(eastl::string name)
870  {
871 
872  if (lights.count(name) <= 0)
873  return glm::vec3(0.f);
874 
875  LightInfo info = lights[name];
876 
877  return glm::vec3(info.light.direction.x, info.light.direction.y, info.light.direction.z);
878  }
879 
880  void VulkanRenderer::SetLightColor(eastl::string name, glm::vec3 color)
881  {
882  if (lights.count(name) <= 0)
883  return;
884 
885  LightInfo info = lights[name];
886 
887  info.light.color.x = color.x;
888  info.light.color.y = color.y;
889  info.light.color.z = color.z;
890 
891  if (info.active) {
892  lightData[info.lightDataIndex] = info.light;
893  lightDataChanged = true;
894  }
895 
896  lights[name] = info;
897  }
898 
899  glm::vec3 VulkanRenderer::GetLightColor(eastl::string name)
900  {
901  if (lights.count(name) <= 0)
902  return glm::vec3(0.f);
903 
904  LightInfo info = lights[name];
905 
906  return glm::vec3(info.light.color.x, info.light.color.y, info.light.color.z);
907  }
908 
909  void VulkanRenderer::SetLightRadius(eastl::string name, float radius)
910  {
911  if (lights.count(name) <= 0)
912  return;
913 
914  LightInfo info = lights[name];
915  info.light.radius = radius;
916  if (info.type == LightType::LIGHT_SPOT_LIGHT || info.type == LightType::LIGHT_POINT_LIGHT) {
917  if (info.active) {
918  lightData[info.lightDataIndex] = info.light;
919  lightDataChanged = true;
920  }
921  }
922  lights[name] = info;
923  }
924 
925  float VulkanRenderer::GetLightRadius(eastl::string name)
926  {
927  if (lights.count(name) == 0)
928  return 0.0f;
929 
930  return lights[name].light.radius;
931  }
932 
933  void VulkanRenderer::SetLightConeInnerAngle(eastl::string name, float angle)
934  {
935  if (lights.count(name) <= 0)
936  return;
937 
938  LightInfo info = lights[name];
939  info.light.coneInnerAngle = angle;
940  if (info.type == LightType::LIGHT_SPOT_LIGHT) {
941  if (info.active) {
942  lightData[info.lightDataIndex] = info.light;
943  lightDataChanged = true;
944  }
945  }
946  lights[name] = info;
947  }
948 
949  float VulkanRenderer::GetLightConeInnerAngle(eastl::string name)
950  {
951  if (lights.count(name) == 0)
952  return 0.0f;
953 
954  return lights[name].light.coneInnerAngle;
955  }
956 
957  void VulkanRenderer::SetLightConeOuterAngle(eastl::string name, float angle)
958  {
959  if (lights.count(name) <= 0)
960  return;
961 
962  LightInfo info = lights[name];
963  info.light.coneOuterAngle = angle;
964  if (info.type == LightType::LIGHT_SPOT_LIGHT) {
965  if (info.active) {
966  lightData[info.lightDataIndex] = info.light;
967  lightDataChanged = true;
968  }
969  }
970  lights[name] = info;
971  }
972 
973  float VulkanRenderer::GetLightConeOuterAngle(eastl::string name)
974  {
975  if (lights.count(name) == 0)
976  return 0.0f;
977 
978  return lights[name].light.coneOuterAngle;
979  }
980 
981  VkDescriptorSetLayout VulkanRenderer::CreateLightDescriptorSetLayout()
982  {
983 
984  eastl::array<VkDescriptorSetLayoutBinding, 2> descriptorSetBindings;
985 
986  descriptorSetBindings[0] = {};
987  descriptorSetBindings[0].binding = 0;
988  descriptorSetBindings[0].descriptorCount = 1;
989  descriptorSetBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
990  descriptorSetBindings[0].pImmutableSamplers = nullptr;
991  descriptorSetBindings[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT;
992 
993  descriptorSetBindings[1] = {};
994  descriptorSetBindings[1].binding = 1;
995  descriptorSetBindings[1].descriptorCount = 1;
996  descriptorSetBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
997  descriptorSetBindings[1].pImmutableSamplers = nullptr;
998  descriptorSetBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT;
999 
1000  VkDescriptorSetLayoutCreateInfo info = {};
1001  info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1002  info.bindingCount = static_cast<uint32_t>(descriptorSetBindings.size());
1003  info.pBindings = descriptorSetBindings.data();
1004  info.flags = 0;
1005 
1006  VkDescriptorSetLayout layout;
1007  vkCreateDescriptorSetLayout(vulkanLogicalDevice_->GetDevice(), &info, nullptr, &layout);
1008 
1009  return layout;
1010  }
1011 
1012  VkDescriptorSet VulkanRenderer::CreateLightDescriptorSet(size_t threadID, size_t pipelineID, size_t set, VkDescriptorSetLayout layout)
1013  {
1014  if (lightDescriptorSets_.size() <= pipelineID) {
1015  lightDescriptorSets_.resize(pipelineID + 1);
1016  }
1017  if (lightDescriptorSets_[pipelineID].size() <= set) {
1018  lightDescriptorSets_[pipelineID].resize(set + 1);
1019  }
1020 
1021  if (lightDescriptorSets_[pipelineID][set].size() <= threadID) {
1022  lightDescriptorSets_[pipelineID][set].resize(threadID + 1, VK_NULL_HANDLE);
1023  }
1024 
1025  if (threadID >= vulkanDescriptorPools_.size())
1026  return VK_NULL_HANDLE;
1027 
1028  VkDescriptorSetLayout layouts[] = { layout };
1029  vulkanDescriptorPools_[threadID]->AllocateDescriptorSet(1, layouts, &lightDescriptorSets_[pipelineID][set][threadID]);
1030 
1031  vulkanDescriptorPools_[threadID]->DescriptorSetBindToBuffer(lightDescriptorSets_[pipelineID][set][threadID], lightBuffer->GetBuffer(),
1032  0, static_cast<uint32_t>(sizeof(Light)), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1);
1033 
1034  vulkanDescriptorPools_[threadID]->DescriptorSetBindToBuffer(lightDescriptorSets_[pipelineID][set][threadID], sceneDataBuffer->GetBuffer(),
1035  0, static_cast<uint32_t>(sizeof(SceneInfo)), 1, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1);
1036 
1037  return lightDescriptorSets_[pipelineID][set][threadID];
1038  }
1039 
1040  VkDescriptorSet VulkanRenderer::GetLightDescriptorSet(size_t threadID, size_t pipelineID, size_t set)
1041  {
1042  if (pipelineID >= lightDescriptorSets_.size())
1043  return VK_NULL_HANDLE;
1044  if (set >= lightDescriptorSets_[pipelineID].size())
1045  return VK_NULL_HANDLE;
1046  if (threadID >= lightDescriptorSets_[pipelineID][set].size())
1047  return VK_NULL_HANDLE;
1048  return lightDescriptorSets_[pipelineID][set][threadID];
1049  }
1050 
1051  VkFramebuffer VulkanRenderer::GetFrameBuffer()
1052  {
1053  return framebuffers[currentImage];
1054  }
1055 
1056  VulkanDescriptorPool* VulkanRenderer::GetDescriptorPool(size_t thread)
1057  {
1058  if (thread >= vulkanDescriptorPools_.size())
1059  return nullptr;
1060  return vulkanDescriptorPools_[thread].get();
1061  }
1062 
1063  size_t VulkanRenderer::GetThreadCount()
1064  {
1065  return threads.size() + 1;
1066  }
1067 
1068  void VulkanRenderer::CreateInstance()
1069  {
1070  vulkanInstance_ = eastl::make_unique<VulkanInstance>(enableValidationLayers, DebugLevel::LEVEL_WARNINGS);
1071  }
1072 
1073  void VulkanRenderer::FindPhysicalDevice()
1074  {
1075  requiredFeatures = {};
1076  requiredFeatures.depthBiasClamp = 1.f;
1077  requiredFeatures.depthBounds = 1.f;
1078  requiredFeatures.depthClamp = 1.f;
1079  requiredFeatures.fillModeNonSolid = 1.f;
1080  requiredFeatures.samplerAnisotropy = 1.f;
1081  requiredFeatures.wideLines = 1.f;
1082  requiredFeatures.largePoints = 1.f;
1083  requiredFeatures.variableMultisampleRate = 1.f;
1084  requiredFeatures.geometryShader = 1.f;
1085 
1086 
1087  VulkanDeviceQueueRequestedFamilies_t requestedQueueFamilies = {};
1088  requestedQueueFamilies.graphics = true;
1089  requestedQueueFamilies.compute = true;
1090  requestedQueueFamilies.present = true;
1091 
1092  vulkanPhysicalDevice_ = eastl::unique_ptr<VulkanPhysicalDevice>(VulkanPhysicalDevice::GetBestPhysicalDevice(
1093  vulkanInstance_.get(), surface, { VK_KHR_SWAPCHAIN_EXTENSION_NAME }, requiredFeatures,
1094  {}, requestedQueueFamilies, true));
1095  }
1096 
1097  void VulkanRenderer::CreateLogicalDevice()
1098  {
1099  vulkanLogicalDevice_ = eastl::unique_ptr<VulkanLogicalDevice>(new VulkanLogicalDevice(
1100  vulkanPhysicalDevice_.get(),
1101  enableValidationLayers,
1102  { VK_KHR_SWAPCHAIN_EXTENSION_NAME },
1103  requiredFeatures));
1104  int x = 8 + 8;
1105  }
1106 
1107  void VulkanRenderer::CreateSwapChain()
1108  {
1109  VulkanSwapChainSupportDetails_t details = vulkanPhysicalDevice_->GetSwapChainSupportDetails();
1110 
1111  VkSurfaceFormatKHR surfaceFormat = vulkanPhysicalDevice_->ChooseSwapSurfaceFormat(details.formats);
1112  VkPresentModeKHR presentMode = vulkanPhysicalDevice_->ChooseSwapPresentMode(details.presentModes);
1113  VkExtent2D extent = vulkanPhysicalDevice_->ChooseSwapExtent(details.capabilities, window.lock()->GetDisplayWidth(), window.lock()->GetDisplayHeight());
1114 
1115  uint32_t imageCount = details.capabilities.minImageCount + 1;
1116  if (details.capabilities.maxImageCount > 0 && imageCount > details.capabilities.maxImageCount) {
1117  imageCount = details.capabilities.maxImageCount;
1118  }
1119 
1120  VkSwapchainCreateInfoKHR createInfo = {};
1121  createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
1122  createInfo.surface = surface;
1123  createInfo.minImageCount = imageCount;
1124  createInfo.imageFormat = surfaceFormat.format;
1125  createInfo.imageColorSpace = surfaceFormat.colorSpace;
1126  createInfo.imageExtent = extent;
1127  createInfo.imageArrayLayers = 1;
1128  createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1129 
1130  VulkanDeviceQueueFamilies_t queueFamilies = vulkanPhysicalDevice_->GetQueueFamilies();
1131  uint32_t queueFamilyIndices[] = { (uint32_t)queueFamilies.graphics, (uint32_t)queueFamilies.present };
1132 
1133  if (queueFamilies.graphics != queueFamilies.present) {
1134  createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
1135  createInfo.queueFamilyIndexCount = 2;
1136  createInfo.pQueueFamilyIndices = queueFamilyIndices;
1137  }
1138  else {
1139  createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
1140  createInfo.queueFamilyIndexCount = 0;
1141  createInfo.pQueueFamilyIndices = nullptr;
1142  }
1143 
1144  createInfo.preTransform = details.capabilities.currentTransform;
1145  createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
1146  createInfo.presentMode = presentMode;
1147  createInfo.clipped = VK_TRUE;
1148  createInfo.oldSwapchain = VK_NULL_HANDLE;
1149 
1150  VkResult res = vkCreateSwapchainKHR(vulkanLogicalDevice_->GetDevice(), &createInfo, nullptr, &swapChain);
1151 
1152  if (res != VK_SUCCESS) {
1153  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create new swapchain";
1154  std::cout << s.c_str() << std::endl;
1155  }
1156 
1157  swapChainImageFormat = surfaceFormat.format;
1158  swapChainImageExtent = extent;
1159  }
1160 
1161  void VulkanRenderer::GetSwapChainImages()
1162  {
1163  imageCount = 0;
1164  vkGetSwapchainImagesKHR(vulkanLogicalDevice_->GetDevice(), swapChain, &imageCount, nullptr);
1165  swapChainImages.resize(imageCount);
1166  vkGetSwapchainImagesKHR(vulkanLogicalDevice_->GetDevice(), swapChain, &imageCount, swapChainImages.data());
1167  }
1168 
1169  void VulkanRenderer::CreateSwapChainImageViews()
1170  {
1171  swapChainImageViews.resize(swapChainImages.size());
1172  for (int i = 0; i < static_cast<int>(swapChainImages.size()); ++i) {
1173  VkImageViewCreateInfo createInfo = {};
1174  createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1175  createInfo.image = swapChainImages[i];
1176  createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1177  createInfo.format = swapChainImageFormat;
1178  createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
1179  createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
1180  createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
1181  createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
1182  createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1183  createInfo.subresourceRange.baseMipLevel = 0;
1184  createInfo.subresourceRange.levelCount = 1;
1185  createInfo.subresourceRange.baseArrayLayer = 0;
1186  createInfo.subresourceRange.layerCount = 1;
1187 
1188  VkResult res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &createInfo, nullptr, &swapChainImageViews[i]);
1189 
1190  if (res != VK_SUCCESS) {
1191  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Image view creation creation failed";
1192  std::cout << s.c_str() << std::endl;
1193  }
1194  }
1195  }
1196 
1197  void VulkanRenderer::CreateGraphicsCommandPool()
1198  {
1199  VkCommandPoolCreateInfo createInfo = {};
1200  createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1201  createInfo.queueFamilyIndex = vulkanPhysicalDevice_->GetQueueFamilies().graphics;
1202  createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1203 
1204  VkResult res = vkCreateCommandPool(vulkanLogicalDevice_->GetDevice(), &createInfo, nullptr, &graphicsCommandPool);
1205  if (res != VK_SUCCESS) {
1206  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Graphics command pool creation failed";
1207  std::cout << s.c_str() << std::endl;
1208  }
1209  }
1210 
1211  void VulkanRenderer::CreateComputeCommandPool()
1212  {
1213  VkCommandPoolCreateInfo createInfo = {};
1214  createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1215  createInfo.queueFamilyIndex = vulkanPhysicalDevice_->GetQueueFamilies().compute;
1216  createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1217 
1218  VkResult res = vkCreateCommandPool(vulkanLogicalDevice_->GetDevice(), &createInfo, nullptr, &computeCommandPool);
1219  if (res != VK_SUCCESS) {
1220  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Graphics command pool creation failed";
1221  std::cout << s.c_str() << std::endl;
1222  }
1223  }
1224 
1225  void VulkanRenderer::CreateVmaAllocator()
1226  {
1227  VmaAllocatorCreateInfo createInfo = {};
1228  createInfo.physicalDevice = vulkanPhysicalDevice_->GetPhysicalDevice();
1229  createInfo.device = vulkanLogicalDevice_->GetDevice();
1230  createInfo.preferredLargeHeapBlockSize = 64 * 1024 * 1024;
1231  createInfo.pAllocationCallbacks = nullptr;
1232  createInfo.pDeviceMemoryCallbacks = nullptr;
1233  createInfo.frameInUseCount = imageCount;
1234  createInfo.pHeapSizeLimit = nullptr;
1235  createInfo.pVulkanFunctions = nullptr;
1236 
1237  VkResult res = vmaCreateAllocator(&createInfo, &vmaAllocator_);
1238  if (res != VK_SUCCESS) {
1239  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create vulkan memory allocator";
1240  std::cout << s.c_str() << std::endl;
1241  }
1242  }
1243 
1244  void VulkanRenderer::CreateDepthImage()
1245  {
1246  VkFormat depthFormat = FindSupportedDepthFormat({ VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT },
1247  VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
1248 
1249  this->depthImageFormat = depthFormat;
1250 
1251  VkImageCreateInfo imageCreateInfo = {};
1252  imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1253  imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1254  imageCreateInfo.extent.width = swapChainImageExtent.width;
1255  imageCreateInfo.extent.height = swapChainImageExtent.height;
1256  imageCreateInfo.extent.depth = 1;
1257  imageCreateInfo.mipLevels = 1;
1258  imageCreateInfo.arrayLayers = 1;
1259  imageCreateInfo.format = depthFormat;
1260  imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1261  imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1262  imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1263  imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1264  imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1265 
1266  VmaAllocationCreateInfo allocInfo = {};
1267  allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1268 
1269  VkResult res = vmaCreateImage(vmaAllocator_, &imageCreateInfo, &allocInfo, &depthImage, &depthImageAllocation, &depthImageAllocationInfo);
1270  if (res != VK_SUCCESS) {
1271  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create depth image";
1272  std::cout << s.c_str() << std::endl;
1273  }
1274 
1275  VkImageViewCreateInfo viewCreateInfo = {};
1276  viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1277  viewCreateInfo.image = depthImage;
1278  viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1279  viewCreateInfo.format = depthFormat;
1280  viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1281  viewCreateInfo.subresourceRange.baseArrayLayer = 0;
1282  viewCreateInfo.subresourceRange.baseMipLevel = 0;
1283  viewCreateInfo.subresourceRange.layerCount = 1;
1284  viewCreateInfo.subresourceRange.levelCount = 1;
1285 
1286  res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &viewCreateInfo, nullptr, &depthImageView);
1287  if (res != VK_SUCCESS) {
1288  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create depth image view";
1289  std::cout << s.c_str() << std::endl;
1290  }
1291 
1292  VkCommandBufferAllocateInfo commandBufferInfo = {};
1293  commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1294  commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1295  commandBufferInfo.commandPool = graphicsCommandPool;
1296  commandBufferInfo.commandBufferCount = 1;
1297 
1298  VkCommandBuffer commandBuffer;
1299  vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &commandBufferInfo, &commandBuffer);
1300 
1301  VkCommandBufferBeginInfo beginInfo = {};
1302  beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1303  beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1304 
1305  vkBeginCommandBuffer(commandBuffer, &beginInfo);
1306 
1307  VkImageMemoryBarrier barrier = {};
1308  barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1309  barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1310  barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1311  barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1312  barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1313  barrier.image = depthImage;
1314  barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1315  barrier.subresourceRange.baseArrayLayer = 0;
1316  barrier.subresourceRange.baseMipLevel = 0;
1317  barrier.subresourceRange.layerCount = 1;
1318  barrier.subresourceRange.levelCount = 1;
1319 
1320  if (depthFormat == VK_FORMAT_D32_SFLOAT_S8_UINT || depthFormat == VK_FORMAT_D24_UNORM_S8_UINT)
1321  barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
1322 
1323  barrier.srcAccessMask = 0;
1324  barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1325 
1326  vkCmdPipelineBarrier(
1327  commandBuffer,
1328  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
1329  0,
1330  0, nullptr,
1331  0, nullptr,
1332  1, &barrier
1333  );
1334 
1335  vkEndCommandBuffer(commandBuffer);
1336 
1337  VkSubmitInfo submitInfo = {};
1338  submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1339  submitInfo.commandBufferCount = 1;
1340  submitInfo.pCommandBuffers = &commandBuffer;
1341 
1342  vkQueueSubmit(vulkanLogicalDevice_->GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
1343  vkQueueWaitIdle(vulkanLogicalDevice_->GetGraphicsQueue());
1344  vkFreeCommandBuffers(vulkanLogicalDevice_->GetDevice(), graphicsCommandPool, 1, &commandBuffer);
1345 
1346  }
1347 
1348  void VulkanRenderer::CreateAttachmentImages()
1349  {
1350  VkImageCreateInfo imguiImageCreateInfo = {};
1351  imguiImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1352  imguiImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1353  imguiImageCreateInfo.extent.width = swapChainImageExtent.width;
1354  imguiImageCreateInfo.extent.height = swapChainImageExtent.height;
1355  imguiImageCreateInfo.extent.depth = 1;
1356  imguiImageCreateInfo.mipLevels = 1;
1357  imguiImageCreateInfo.arrayLayers = 1;
1358  imguiImageCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
1359  imguiImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1360  imguiImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1361  imguiImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1362  imguiImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1363  imguiImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1364 
1365  VmaAllocationCreateInfo allocInfo = {};
1366  allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1367 
1368  VkResult res = vmaCreateImage(vmaAllocator_, &imguiImageCreateInfo, &allocInfo, &imguiImage, &imguiImageAllocation, &imguiImageAllocationInfo);
1369  if (res != VK_SUCCESS) {
1370  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create imgui image";
1371  std::cout << s.c_str() << std::endl;
1372  }
1373 
1374  VkImageViewCreateInfo imguiViewCreateInfo = {};
1375  imguiViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1376  imguiViewCreateInfo.image = imguiImage;
1377  imguiViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1378  imguiViewCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
1379  imguiViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1380  imguiViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1381  imguiViewCreateInfo.subresourceRange.baseMipLevel = 0;
1382  imguiViewCreateInfo.subresourceRange.layerCount = 1;
1383  imguiViewCreateInfo.subresourceRange.levelCount = 1;
1384 
1385  res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &imguiViewCreateInfo, nullptr, &imguiImageView);
1386  if (res != VK_SUCCESS) {
1387  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create imgui image view";
1388  std::cout << s.c_str() << std::endl;
1389  }
1390 
1391  VkImageCreateInfo renderImageCreateInfo = {};
1392  renderImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1393  renderImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1394  renderImageCreateInfo.extent.width = swapChainImageExtent.width;
1395  renderImageCreateInfo.extent.height = swapChainImageExtent.height;
1396  renderImageCreateInfo.extent.depth = 1;
1397  renderImageCreateInfo.mipLevels = 1;
1398  renderImageCreateInfo.arrayLayers = 1;
1399  renderImageCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
1400  renderImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1401  renderImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1402  renderImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1403  renderImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1404  renderImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1405 
1406  allocInfo = {};
1407  allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1408 
1409  res = vmaCreateImage(vmaAllocator_, &renderImageCreateInfo, &allocInfo, &renderImage, &renderImageAllocation, &renderImageAllocationInfo);
1410  if (res != VK_SUCCESS) {
1411  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create render image";
1412  std::cout << s.c_str() << std::endl;
1413  }
1414 
1415  VkImageViewCreateInfo renderViewCreateInfo = {};
1416  renderViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1417  renderViewCreateInfo.image = renderImage;
1418  renderViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1419  renderViewCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
1420  renderViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1421  renderViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1422  renderViewCreateInfo.subresourceRange.baseMipLevel = 0;
1423  renderViewCreateInfo.subresourceRange.layerCount = 1;
1424  renderViewCreateInfo.subresourceRange.levelCount = 1;
1425 
1426  res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &renderViewCreateInfo, nullptr, &renderImageView);
1427  if (res != VK_SUCCESS) {
1428  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create render image view";
1429  std::cout << s.c_str() << std::endl;
1430  }
1431 
1432  VkImageCreateInfo albedoImageCreateInfo = {};
1433  albedoImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1434  albedoImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1435  albedoImageCreateInfo.extent.width = swapChainImageExtent.width;
1436  albedoImageCreateInfo.extent.height = swapChainImageExtent.height;
1437  albedoImageCreateInfo.extent.depth = 1;
1438  albedoImageCreateInfo.mipLevels = 1;
1439  albedoImageCreateInfo.arrayLayers = 1;
1440  albedoImageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
1441  albedoImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1442  albedoImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1443  albedoImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1444  albedoImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1445  albedoImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1446 
1447  allocInfo = {};
1448  allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1449 
1450  res = vmaCreateImage(vmaAllocator_, &albedoImageCreateInfo, &allocInfo, &albedoImage, &albedoImageAllocation, &albedoImageAllocationInfo);
1451  if (res != VK_SUCCESS) {
1452  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create albedo image";
1453  std::cout << s.c_str() << std::endl;
1454  }
1455 
1456  VkImageViewCreateInfo albedoViewCreateInfo = {};
1457  albedoViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1458  albedoViewCreateInfo.image = albedoImage;
1459  albedoViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1460  albedoViewCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
1461  albedoViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1462  albedoViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1463  albedoViewCreateInfo.subresourceRange.baseMipLevel = 0;
1464  albedoViewCreateInfo.subresourceRange.layerCount = 1;
1465  albedoViewCreateInfo.subresourceRange.levelCount = 1;
1466 
1467  res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &albedoViewCreateInfo, nullptr, &albedoImageView);
1468  if (res != VK_SUCCESS) {
1469  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create albedo image view";
1470  std::cout << s.c_str() << std::endl;
1471  }
1472 
1473  VkImageCreateInfo positionImageCreateInfo = {};
1474  positionImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1475  positionImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1476  positionImageCreateInfo.extent.width = swapChainImageExtent.width;
1477  positionImageCreateInfo.extent.height = swapChainImageExtent.height;
1478  positionImageCreateInfo.extent.depth = 1;
1479  positionImageCreateInfo.mipLevels = 1;
1480  positionImageCreateInfo.arrayLayers = 1;
1481  positionImageCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
1482  positionImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1483  positionImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1484  positionImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1485  positionImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1486  positionImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1487 
1488  allocInfo = {};
1489  allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1490 
1491  res = vmaCreateImage(vmaAllocator_, &positionImageCreateInfo, &allocInfo, &positionImage, &positionImageAllocation, &positionImageAllocationInfo);
1492  if (res != VK_SUCCESS) {
1493  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create position image";
1494  std::cout << s.c_str() << std::endl;
1495  }
1496 
1497  VkImageViewCreateInfo positionViewCreateInfo = {};
1498  positionViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1499  positionViewCreateInfo.image = positionImage;
1500  positionViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1501  positionViewCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
1502  positionViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1503  positionViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1504  positionViewCreateInfo.subresourceRange.baseMipLevel = 0;
1505  positionViewCreateInfo.subresourceRange.layerCount = 1;
1506  positionViewCreateInfo.subresourceRange.levelCount = 1;
1507 
1508  res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &positionViewCreateInfo, nullptr, &positionImageView);
1509  if (res != VK_SUCCESS) {
1510  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create position image view";
1511  std::cout << s.c_str() << std::endl;
1512  }
1513 
1514  VkImageCreateInfo normalImageCreateInfo = {};
1515  normalImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1516  normalImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1517  normalImageCreateInfo.extent.width = swapChainImageExtent.width;
1518  normalImageCreateInfo.extent.height = swapChainImageExtent.height;
1519  normalImageCreateInfo.extent.depth = 1;
1520  normalImageCreateInfo.mipLevels = 1;
1521  normalImageCreateInfo.arrayLayers = 1;
1522  normalImageCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
1523  normalImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1524  normalImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1525  normalImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1526  normalImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1527  normalImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1528 
1529  allocInfo = {};
1530  allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1531 
1532  res = vmaCreateImage(vmaAllocator_, &normalImageCreateInfo, &allocInfo, &normalImage, &normalImageAllocation, &normalImageAllocationInfo);
1533  if (res != VK_SUCCESS) {
1534  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create normal image";
1535  std::cout << s.c_str() << std::endl;
1536  }
1537 
1538  VkImageViewCreateInfo normalViewCreateInfo = {};
1539  normalViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1540  normalViewCreateInfo.image = normalImage;
1541  normalViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1542  normalViewCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
1543  normalViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1544  normalViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1545  normalViewCreateInfo.subresourceRange.baseMipLevel = 0;
1546  normalViewCreateInfo.subresourceRange.layerCount = 1;
1547  normalViewCreateInfo.subresourceRange.levelCount = 1;
1548 
1549  res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &normalViewCreateInfo, nullptr, &normalImageView);
1550  if (res != VK_SUCCESS) {
1551  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create normal image view";
1552  std::cout << s.c_str() << std::endl;
1553  }
1554 
1555 
1556  VkImageCreateInfo ssaoImageCreateInfo = {};
1557  ssaoImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1558  ssaoImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1559  ssaoImageCreateInfo.extent.width = swapChainImageExtent.width;
1560  ssaoImageCreateInfo.extent.height = swapChainImageExtent.height;
1561  ssaoImageCreateInfo.extent.depth = 1;
1562  ssaoImageCreateInfo.mipLevels = 1;
1563  ssaoImageCreateInfo.arrayLayers = 1;
1564  ssaoImageCreateInfo.format = VK_FORMAT_R16_UNORM;
1565  ssaoImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1566  ssaoImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1567  ssaoImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1568  ssaoImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1569  ssaoImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1570 
1571  allocInfo = {};
1572  allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1573 
1574  res = vmaCreateImage(vmaAllocator_, &ssaoImageCreateInfo, &allocInfo, &ssaoImage, &ssaoImageAllocation, &ssaoImageAllocationInfo);
1575  if (res != VK_SUCCESS) {
1576  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create ssao image";
1577  std::cout << s.c_str() << std::endl;
1578  }
1579 
1580  VkImageViewCreateInfo ssaoViewCreateInfo = {};
1581  ssaoViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1582  ssaoViewCreateInfo.image = ssaoImage;
1583  ssaoViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1584  ssaoViewCreateInfo.format = VK_FORMAT_R16_UNORM;
1585  ssaoViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1586  ssaoViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1587  ssaoViewCreateInfo.subresourceRange.baseMipLevel = 0;
1588  ssaoViewCreateInfo.subresourceRange.layerCount = 1;
1589  ssaoViewCreateInfo.subresourceRange.levelCount = 1;
1590 
1591  res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &ssaoViewCreateInfo, nullptr, &ssaoImageView);
1592  if (res != VK_SUCCESS) {
1593  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create ssao image view";
1594  std::cout << s.c_str() << std::endl;
1595  }
1596 
1597  VkImageCreateInfo ssaoBlurImageCreateInfo = {};
1598  ssaoBlurImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1599  ssaoBlurImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1600  ssaoBlurImageCreateInfo.extent.width = swapChainImageExtent.width;
1601  ssaoBlurImageCreateInfo.extent.height = swapChainImageExtent.height;
1602  ssaoBlurImageCreateInfo.extent.depth = 1;
1603  ssaoBlurImageCreateInfo.mipLevels = 1;
1604  ssaoBlurImageCreateInfo.arrayLayers = 1;
1605  ssaoBlurImageCreateInfo.format = VK_FORMAT_R16_UNORM;
1606  ssaoBlurImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1607  ssaoBlurImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1608  ssaoBlurImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1609  ssaoBlurImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1610  ssaoBlurImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1611 
1612  allocInfo = {};
1613  allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1614 
1615  res = vmaCreateImage(vmaAllocator_, &ssaoBlurImageCreateInfo, &allocInfo, &ssaoBlurImage, &ssaoBlurImageAllocation, &ssaoBlurImageAllocationInfo);
1616  if (res != VK_SUCCESS) {
1617  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create ssaoBlur image";
1618  std::cout << s.c_str() << std::endl;
1619  }
1620 
1621  VkImageViewCreateInfo ssaoBlurViewCreateInfo = {};
1622  ssaoBlurViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1623  ssaoBlurViewCreateInfo.image = ssaoBlurImage;
1624  ssaoBlurViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1625  ssaoBlurViewCreateInfo.format = VK_FORMAT_R16_UNORM;
1626  ssaoBlurViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1627  ssaoBlurViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1628  ssaoBlurViewCreateInfo.subresourceRange.baseMipLevel = 0;
1629  ssaoBlurViewCreateInfo.subresourceRange.layerCount = 1;
1630  ssaoBlurViewCreateInfo.subresourceRange.levelCount = 1;
1631 
1632  res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &ssaoBlurViewCreateInfo, nullptr, &ssaoBlurImageView);
1633  if (res != VK_SUCCESS) {
1634  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Failed to create ssaoBlur image view";
1635  std::cout << s.c_str() << std::endl;
1636  }
1637 
1638  }
1639 
1640  void VulkanRenderer::CreateRenderPass()
1641  {
1642 
1643  gBufferPassAttachments.resize(static_cast<size_t>(GBufferAttachments::ATTACHMENT_COUNT));
1644 
1645  gBufferPassAttachments[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].flags = 0;
1646  gBufferPassAttachments[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].format = depthImageFormat;
1647  gBufferPassAttachments[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1648  gBufferPassAttachments[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1649  gBufferPassAttachments[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1650  gBufferPassAttachments[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1651  gBufferPassAttachments[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1652  gBufferPassAttachments[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1653  gBufferPassAttachments[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1654 
1655  gBufferPassAttachments[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].flags = 0;
1656  gBufferPassAttachments[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].format = VK_FORMAT_R8G8B8A8_UNORM;
1657  gBufferPassAttachments[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1658  gBufferPassAttachments[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1659  gBufferPassAttachments[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1660  gBufferPassAttachments[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1661  gBufferPassAttachments[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1662  gBufferPassAttachments[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1663  gBufferPassAttachments[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1664 
1665  gBufferPassAttachments[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].flags = 0;
1666  gBufferPassAttachments[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].format = VK_FORMAT_R16G16B16A16_SFLOAT;
1667  gBufferPassAttachments[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1668  gBufferPassAttachments[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1669  gBufferPassAttachments[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1670  gBufferPassAttachments[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1671  gBufferPassAttachments[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1672  gBufferPassAttachments[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1673  gBufferPassAttachments[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1674 
1675  gBufferPassAttachments[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].flags = 0;
1676  gBufferPassAttachments[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].format = VK_FORMAT_R16G16B16A16_SFLOAT;
1677  gBufferPassAttachments[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1678  gBufferPassAttachments[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1679  gBufferPassAttachments[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1680  gBufferPassAttachments[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1681  gBufferPassAttachments[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1682  gBufferPassAttachments[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1683  gBufferPassAttachments[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1684 
1685 
1686 
1687  ssaoPassAttachments.resize(static_cast<size_t>(SsaoAttachments::ATTACHMENT_COUNT));
1688 
1689  ssaoPassAttachments[static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].flags = 0;
1690  ssaoPassAttachments[static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].format = VK_FORMAT_R16_UNORM;
1691  ssaoPassAttachments[static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1692  ssaoPassAttachments[static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1693  ssaoPassAttachments[static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1694  ssaoPassAttachments[static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1695  ssaoPassAttachments[static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1696  ssaoPassAttachments[static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1697  ssaoPassAttachments[static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1698 
1699  renderPassAttachments.resize(static_cast<int>(RenderPassAttachments::ATTACHMENT_COUNT));
1700 
1701  renderPassAttachments[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].flags = 0;
1702  renderPassAttachments[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].format = VK_FORMAT_B8G8R8A8_UNORM;
1703  renderPassAttachments[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1704  renderPassAttachments[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1705  renderPassAttachments[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1706  renderPassAttachments[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1707  renderPassAttachments[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1708  renderPassAttachments[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1709  renderPassAttachments[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
1710 
1711  renderPassAttachments[static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].flags = 0;
1712  renderPassAttachments[static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].format = depthImageFormat;
1713  renderPassAttachments[static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1714  renderPassAttachments[static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1715  renderPassAttachments[static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1716  renderPassAttachments[static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1717  renderPassAttachments[static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1718  renderPassAttachments[static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1719  renderPassAttachments[static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1720 
1721  renderPassAttachments[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].flags = 0;
1722  renderPassAttachments[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].format = VK_FORMAT_R16_UNORM;
1723  renderPassAttachments[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1724  renderPassAttachments[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1725  renderPassAttachments[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1726  renderPassAttachments[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1727  renderPassAttachments[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1728  renderPassAttachments[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1729  renderPassAttachments[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1730 
1731  renderPassAttachments[static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].flags = 0;
1732  renderPassAttachments[static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].format = VK_FORMAT_R8G8B8A8_UNORM;
1733  renderPassAttachments[static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1734  renderPassAttachments[static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1735  renderPassAttachments[static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1736  renderPassAttachments[static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1737  renderPassAttachments[static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1738  renderPassAttachments[static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1739  renderPassAttachments[static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1740 
1741  renderPassAttachments[static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].flags = 0;
1742  renderPassAttachments[static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].format = VK_FORMAT_R16G16B16A16_SFLOAT;
1743  renderPassAttachments[static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1744  renderPassAttachments[static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1745  renderPassAttachments[static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1746  renderPassAttachments[static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1747  renderPassAttachments[static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1748  renderPassAttachments[static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1749  renderPassAttachments[static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1750 
1751  renderPassAttachments[static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].flags = 0;
1752  renderPassAttachments[static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].format = VK_FORMAT_R16G16B16A16_SFLOAT;
1753  renderPassAttachments[static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1754  renderPassAttachments[static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1755  renderPassAttachments[static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1756  renderPassAttachments[static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1757  renderPassAttachments[static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1758  renderPassAttachments[static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1759  renderPassAttachments[static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1760 
1761  renderPassAttachments[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].flags = 0;
1762  renderPassAttachments[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].format = VK_FORMAT_B8G8R8A8_UNORM;
1763  renderPassAttachments[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1764  renderPassAttachments[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1765  renderPassAttachments[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1766  renderPassAttachments[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1767  renderPassAttachments[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1768  renderPassAttachments[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1769  renderPassAttachments[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1770 
1771  renderPassAttachments[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].flags = 0;
1772  renderPassAttachments[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].format = VK_FORMAT_B8G8R8A8_UNORM;
1773  renderPassAttachments[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1774  renderPassAttachments[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1775  renderPassAttachments[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1776  renderPassAttachments[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1777  renderPassAttachments[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1778  renderPassAttachments[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1779  renderPassAttachments[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1780 
1781 
1782  gBufferPassSubPasses.resize(static_cast<int>(GBufferSubPasses::SUBPASS_COUNT));
1783 
1784  VkAttachmentReference gBufferDepthReference = {};
1785  gBufferDepthReference.attachment = static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT);
1786  gBufferDepthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1787 
1788  VkAttachmentReference gBufferAttachments[] = {
1789  {
1790  static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT),
1791  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1792  },
1793  {
1794  static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT),
1795  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1796  },
1797  {
1798  static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT),
1799  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1800  }
1801  };
1802 
1803  gBufferPassSubPasses[static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].flags = 0;
1804  gBufferPassSubPasses[static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1805  gBufferPassSubPasses[static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].inputAttachmentCount = 0;
1806  gBufferPassSubPasses[static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pInputAttachments = nullptr;
1807  gBufferPassSubPasses[static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].colorAttachmentCount = 3;
1808  gBufferPassSubPasses[static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pColorAttachments = gBufferAttachments;
1809  gBufferPassSubPasses[static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pResolveAttachments = nullptr;
1810  gBufferPassSubPasses[static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pDepthStencilAttachment = &gBufferDepthReference;
1811  gBufferPassSubPasses[static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].preserveAttachmentCount = 0;
1812  gBufferPassSubPasses[static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pPreserveAttachments = nullptr;
1813 
1814  eastl::vector<VkSubpassDependency> gbufferDependencies = {
1815  {
1816  VK_SUBPASS_EXTERNAL,
1817  static_cast<int>(GBufferSubPasses::G_BUFFER_PASS),
1818  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1819  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1820  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1821  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
1822  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1823  VK_DEPENDENCY_BY_REGION_BIT
1824  },
1825  {
1826  static_cast<int>(GBufferSubPasses::G_BUFFER_PASS),
1827  VK_SUBPASS_EXTERNAL,
1828  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1829  VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
1830  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
1831  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1832  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1833  VK_DEPENDENCY_BY_REGION_BIT
1834  }
1835  };
1836 
1837  VkRenderPassCreateInfo gbufferPassCreateInfo = {};
1838  gbufferPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
1839  gbufferPassCreateInfo.attachmentCount = static_cast<uint32_t>(gBufferPassAttachments.size());
1840  gbufferPassCreateInfo.pAttachments = gBufferPassAttachments.data();
1841  gbufferPassCreateInfo.dependencyCount = static_cast<uint32_t>(gbufferDependencies.size());
1842  gbufferPassCreateInfo.pDependencies = gbufferDependencies.data();
1843  gbufferPassCreateInfo.subpassCount = static_cast<uint32_t>(gBufferPassSubPasses.size());
1844  gbufferPassCreateInfo.pSubpasses = gBufferPassSubPasses.data();
1845  gbufferPassCreateInfo.flags = 0;
1846 
1847  vkCreateRenderPass(vulkanLogicalDevice_->GetDevice(), &gbufferPassCreateInfo, nullptr, &gBufferPass);
1848 
1849  ssaoPassSubPasses.resize(static_cast<int>(SsaoSubPasses::SUBPASS_COUNT));
1850 
1851  VkAttachmentReference ssaoReference = {};
1852  ssaoReference.attachment = static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT);
1853  ssaoReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1854 
1855  ssaoPassSubPasses[static_cast<int>(SsaoSubPasses::SSAO_PASS)].flags = 0;
1856  ssaoPassSubPasses[static_cast<int>(SsaoSubPasses::SSAO_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1857  ssaoPassSubPasses[static_cast<int>(SsaoSubPasses::SSAO_PASS)].inputAttachmentCount = 0;
1858  ssaoPassSubPasses[static_cast<int>(SsaoSubPasses::SSAO_PASS)].pInputAttachments = nullptr;
1859  ssaoPassSubPasses[static_cast<int>(SsaoSubPasses::SSAO_PASS)].colorAttachmentCount = 1;
1860  ssaoPassSubPasses[static_cast<int>(SsaoSubPasses::SSAO_PASS)].pColorAttachments = &ssaoReference;
1861  ssaoPassSubPasses[static_cast<int>(SsaoSubPasses::SSAO_PASS)].pResolveAttachments = nullptr;
1862  ssaoPassSubPasses[static_cast<int>(SsaoSubPasses::SSAO_PASS)].pDepthStencilAttachment = nullptr;
1863  ssaoPassSubPasses[static_cast<int>(SsaoSubPasses::SSAO_PASS)].preserveAttachmentCount = 0;
1864  ssaoPassSubPasses[static_cast<int>(SsaoSubPasses::SSAO_PASS)].pPreserveAttachments = nullptr;
1865 
1866  eastl::vector<VkSubpassDependency> ssaoDependencies = {
1867  {
1868  VK_SUBPASS_EXTERNAL,
1869  static_cast<int>(SsaoSubPasses::SSAO_PASS),
1870  VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
1871  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1872  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1873  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1874  VK_DEPENDENCY_BY_REGION_BIT
1875  },
1876  {
1877  static_cast<int>(SsaoSubPasses::SSAO_PASS),
1878  VK_SUBPASS_EXTERNAL,
1879  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1880  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1881  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1882  VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1883  VK_DEPENDENCY_BY_REGION_BIT
1884  }
1885  };
1886 
1887  VkRenderPassCreateInfo ssaoPassCreateInfo = {};
1888  ssaoPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
1889  ssaoPassCreateInfo.attachmentCount = static_cast<uint32_t>(ssaoPassAttachments.size());
1890  ssaoPassCreateInfo.pAttachments = ssaoPassAttachments.data();
1891  ssaoPassCreateInfo.dependencyCount = static_cast<uint32_t>(ssaoDependencies.size());
1892  ssaoPassCreateInfo.pDependencies = ssaoDependencies.data();
1893  ssaoPassCreateInfo.subpassCount = static_cast<uint32_t>(ssaoPassSubPasses.size());
1894  ssaoPassCreateInfo.pSubpasses = ssaoPassSubPasses.data();
1895  ssaoPassCreateInfo.flags = 0;
1896 
1897  vkCreateRenderPass(vulkanLogicalDevice_->GetDevice(), &ssaoPassCreateInfo, nullptr, &ssaoPass);
1898 
1899  renderPassSubPasses.resize(static_cast<int>(RenderSubPasses::SUBPASS_COUNT));
1900 
1901  VkAttachmentReference ssaoBlurReference = {};
1902  ssaoBlurReference.attachment = static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT);
1903  ssaoBlurReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1904 
1905  renderPassSubPasses[static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].flags = 0;
1906  renderPassSubPasses[static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1907  renderPassSubPasses[static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].inputAttachmentCount = 0;
1908  renderPassSubPasses[static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pInputAttachments = nullptr;
1909  renderPassSubPasses[static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].colorAttachmentCount = 1;
1910  renderPassSubPasses[static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pColorAttachments = &ssaoBlurReference;
1911  renderPassSubPasses[static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pResolveAttachments = nullptr;
1912  renderPassSubPasses[static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pDepthStencilAttachment = nullptr;
1913  renderPassSubPasses[static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].preserveAttachmentCount = 0;
1914  renderPassSubPasses[static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pPreserveAttachments = nullptr;
1915 
1916  VkAttachmentReference renderDepthReference = {};
1917  renderDepthReference.attachment = static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT);
1918  renderDepthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
1919 
1920  VkAttachmentReference gBufferInputs[] = {
1921  {
1922  static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT),
1923  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1924  },
1925  {
1926  static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT),
1927  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1928  },
1929  {
1930  static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT),
1931  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1932  }
1933  };
1934 
1935  VkAttachmentReference renderReference = {};
1936  renderReference.attachment = static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT);
1937  renderReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1938 
1939  renderPassSubPasses[static_cast<int>(RenderSubPasses::RENDER_PASS)].flags = 0;
1940  renderPassSubPasses[static_cast<int>(RenderSubPasses::RENDER_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1941  renderPassSubPasses[static_cast<int>(RenderSubPasses::RENDER_PASS)].inputAttachmentCount = 3;
1942  renderPassSubPasses[static_cast<int>(RenderSubPasses::RENDER_PASS)].pInputAttachments = gBufferInputs;
1943  renderPassSubPasses[static_cast<int>(RenderSubPasses::RENDER_PASS)].colorAttachmentCount = 1;
1944  renderPassSubPasses[static_cast<int>(RenderSubPasses::RENDER_PASS)].pColorAttachments = &renderReference;
1945  renderPassSubPasses[static_cast<int>(RenderSubPasses::RENDER_PASS)].pResolveAttachments = nullptr;
1946  renderPassSubPasses[static_cast<int>(RenderSubPasses::RENDER_PASS)].pDepthStencilAttachment = &renderDepthReference;
1947  renderPassSubPasses[static_cast<int>(RenderSubPasses::RENDER_PASS)].preserveAttachmentCount = 0;
1948  renderPassSubPasses[static_cast<int>(RenderSubPasses::RENDER_PASS)].pPreserveAttachments = nullptr;
1949 
1950  VkAttachmentReference imguiReference = {};
1951  imguiReference.attachment = static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT);
1952  imguiReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1953 
1954  renderPassSubPasses[static_cast<int>(RenderSubPasses::IMGUI_PASS)].flags = 0;
1955  renderPassSubPasses[static_cast<int>(RenderSubPasses::IMGUI_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1956  renderPassSubPasses[static_cast<int>(RenderSubPasses::IMGUI_PASS)].inputAttachmentCount = 0;
1957  renderPassSubPasses[static_cast<int>(RenderSubPasses::IMGUI_PASS)].pInputAttachments = nullptr;
1958  renderPassSubPasses[static_cast<int>(RenderSubPasses::IMGUI_PASS)].colorAttachmentCount = 1;
1959  renderPassSubPasses[static_cast<int>(RenderSubPasses::IMGUI_PASS)].pColorAttachments = &imguiReference;
1960  renderPassSubPasses[static_cast<int>(RenderSubPasses::IMGUI_PASS)].pResolveAttachments = nullptr;
1961  renderPassSubPasses[static_cast<int>(RenderSubPasses::IMGUI_PASS)].pDepthStencilAttachment = nullptr;
1962  renderPassSubPasses[static_cast<int>(RenderSubPasses::IMGUI_PASS)].preserveAttachmentCount = 0;
1963  renderPassSubPasses[static_cast<int>(RenderSubPasses::IMGUI_PASS)].pPreserveAttachments = nullptr;
1964 
1965  VkAttachmentReference compositeInputs[] = {
1966  {
1967  static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT),
1968  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1969  },
1970 
1971  {
1972  static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT),
1973  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1974  }
1975  };
1976 
1977  VkAttachmentReference compositeReference = {};
1978  compositeReference.attachment = static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT);
1979  compositeReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1980 
1981  renderPassSubPasses[static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].flags = 0;
1982  renderPassSubPasses[static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1983  renderPassSubPasses[static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].inputAttachmentCount = 2;
1984  renderPassSubPasses[static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pInputAttachments = compositeInputs;
1985  renderPassSubPasses[static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].colorAttachmentCount = 1;
1986  renderPassSubPasses[static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pColorAttachments = &compositeReference;
1987  renderPassSubPasses[static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pResolveAttachments = nullptr;
1988  renderPassSubPasses[static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pDepthStencilAttachment = nullptr;
1989  renderPassSubPasses[static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].preserveAttachmentCount = 0;
1990  renderPassSubPasses[static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pPreserveAttachments = nullptr;
1991 
1992 
1993 
1994  eastl::vector<VkSubpassDependency> dependecies = {
1995  {
1996  VK_SUBPASS_EXTERNAL,
1997  static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS),
1998  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1999  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2000  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2001  VK_ACCESS_SHADER_READ_BIT,
2002  VK_DEPENDENCY_BY_REGION_BIT
2003  },
2004 
2005  {
2006  static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS),
2007  static_cast<int>(RenderSubPasses::RENDER_PASS),
2008  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2009  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2010  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2011  VK_ACCESS_SHADER_READ_BIT,
2012  VK_DEPENDENCY_BY_REGION_BIT
2013  },
2014 
2015  {
2016  static_cast<int>(RenderSubPasses::RENDER_PASS),
2017  static_cast<int>(RenderSubPasses::COMPOSITE_PASS),
2018  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2019  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2020  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2021  VK_ACCESS_SHADER_READ_BIT,
2022  VK_DEPENDENCY_BY_REGION_BIT
2023  },
2024 
2025  {
2026  static_cast<int>(RenderSubPasses::IMGUI_PASS),
2027  static_cast<int>(RenderSubPasses::COMPOSITE_PASS),
2028  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2029  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2030  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2031  VK_ACCESS_SHADER_READ_BIT,
2032  VK_DEPENDENCY_BY_REGION_BIT
2033  },
2034 
2035  {
2036  static_cast<int>(RenderSubPasses::COMPOSITE_PASS),
2037  VK_SUBPASS_EXTERNAL,
2038  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2039  VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
2040  VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2041  VK_ACCESS_SHADER_READ_BIT,
2042  VK_DEPENDENCY_BY_REGION_BIT
2043  }
2044  };
2045 
2046  VkRenderPassCreateInfo createInfo = {};
2047  createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
2048  createInfo.flags = 0;
2049  createInfo.attachmentCount = static_cast<uint32_t>(renderPassAttachments.size());
2050  createInfo.pAttachments = renderPassAttachments.data();
2051  createInfo.subpassCount = static_cast<uint32_t>(renderPassSubPasses.size());
2052  createInfo.pSubpasses = renderPassSubPasses.data();
2053  createInfo.dependencyCount = static_cast<uint32_t>(dependecies.size());
2054  createInfo.pDependencies = dependecies.data();
2055 
2056  VkResult res = vkCreateRenderPass(vulkanLogicalDevice_->GetDevice(), &createInfo, nullptr, &renderPass);
2057  }
2058 
2059  void VulkanRenderer::CreateFramebuffers()
2060  {
2061  framebuffers.resize(swapChainImageViews.size());
2062 
2063  for (int i = 0; i < framebuffers.size(); ++i) {
2064  eastl::vector<VkImageView> attachments(static_cast<int>(RenderPassAttachments::ATTACHMENT_COUNT));
2065  attachments[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)] = swapChainImageViews[i];
2066  attachments[static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)] = depthImageView;
2067  attachments[static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)] = imguiImageView;
2068  attachments[static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)] = renderImageView;
2069  attachments[static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)] = albedoImageView;
2070  attachments[static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)] = positionImageView;
2071  attachments[static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)] = normalImageView;
2072  attachments[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)] = ssaoBlurImageView;
2073 
2074  VkFramebufferCreateInfo createInfo = {};
2075  createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2076  createInfo.renderPass = renderPass;
2077  createInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
2078  createInfo.pAttachments = attachments.data();
2079  createInfo.width = swapChainImageExtent.width;
2080  createInfo.height = swapChainImageExtent.height;
2081  createInfo.layers = 1;
2082 
2083  VkResult res = vkCreateFramebuffer(vulkanLogicalDevice_->GetDevice(), &createInfo, nullptr, &framebuffers[i]);
2084  if (res != VK_SUCCESS) {
2085  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Framebuffer creation failed";
2086  std::cout << s.c_str() << std::endl;
2087  }
2088  }
2089  eastl::vector<VkImageView> attachments(static_cast<int>(GBufferAttachments::ATTACHMENT_COUNT));
2090  attachments[static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)] = depthImageView;
2091  attachments[static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)] = albedoImageView;
2092  attachments[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)] = positionImageView;
2093  attachments[static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)] = normalImageView;
2094 
2095  VkFramebufferCreateInfo createInfo = {};
2096  createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2097  createInfo.renderPass = gBufferPass;
2098  createInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
2099  createInfo.pAttachments = attachments.data();
2100  createInfo.width = swapChainImageExtent.width;
2101  createInfo.height = swapChainImageExtent.height;
2102  createInfo.layers = 1;
2103 
2104  VkResult res = vkCreateFramebuffer(vulkanLogicalDevice_->GetDevice(), &createInfo, nullptr, &gBufferFrameBuffer);
2105  if (res != VK_SUCCESS) {
2106  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Framebuffer creation failed";
2107  std::cout << s.c_str() << std::endl;
2108  }
2109 
2110  attachments.resize(static_cast<int>(SsaoAttachments::ATTACHMENT_COUNT));
2111  attachments[static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)] = ssaoImageView;
2112 
2113  createInfo = {};
2114  createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2115  createInfo.renderPass = ssaoPass;
2116  createInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
2117  createInfo.pAttachments = attachments.data();
2118  createInfo.width = swapChainImageExtent.width;
2119  createInfo.height = swapChainImageExtent.height;
2120  createInfo.layers = 1;
2121 
2122  res = vkCreateFramebuffer(vulkanLogicalDevice_->GetDevice(), &createInfo, nullptr, &ssaoFrameBuffer);
2123  if (res != VK_SUCCESS) {
2124  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Framebuffer creation failed";
2125  std::cout << s.c_str() << std::endl;
2126  }
2127  }
2128 
2129  void VulkanRenderer::GenerateCommandBuffers()
2130  {
2131  primaryRenderCommandBuffers_.resize(framebuffers.size());
2132 
2133  VkCommandBufferAllocateInfo allocInfo = {};
2134  allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2135  allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2136  allocInfo.commandPool = graphicsCommandPool;
2137  allocInfo.commandBufferCount = static_cast<uint32_t>(primaryRenderCommandBuffers_.size());
2138 
2139  vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &allocInfo, primaryRenderCommandBuffers_.data());
2140 
2141  primaryComputeCommandBuffers_.resize(framebuffers.size());
2142 
2143  allocInfo.commandPool = computeCommandPool;
2144  vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &allocInfo, primaryComputeCommandBuffers_.data());
2145 
2146  imguiCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2147  spriteRenderCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2148  debugRenderCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2149  staticMeshCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2150  skeletalMeshCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2151  clearStencilCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2152 
2153  staticMeshShadowCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2154  skeletalMeshShadowCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2155  gBufferShadowCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2156 
2157  GenerateSecondaryCommandBuffers(imguiCommandBuffers_.data(), static_cast<uint32_t>(imguiCommandBuffers_.size()));
2158 
2159  GenerateSecondaryCommandBuffers(&compositeCommandBuffer_, 1);
2160 
2161  GenerateSecondaryCommandBuffers(&gBufferRenderCommandBuffer_, 1);
2162 
2163  GenerateSecondaryCommandBuffers(spriteRenderCommandBuffers_.data(), static_cast<uint32_t>(spriteRenderCommandBuffers_.size()));
2164 
2165  GenerateSecondaryCommandBuffers(debugRenderCommandBuffers_.data(), static_cast<uint32_t>(debugRenderCommandBuffers_.size()));
2166 
2167  GenerateSecondaryCommandBuffers(clearStencilCommandBuffers_.data(), static_cast<uint32_t>(clearStencilCommandBuffers_.size()));
2168 
2169  GenerateSecondaryCommandBuffers(staticMeshCommandBuffers_.data(), static_cast<uint32_t>(staticMeshCommandBuffers_.size()));
2170 
2171  GenerateSecondaryCommandBuffers(skeletalMeshCommandBuffers_.data(), static_cast<uint32_t>(skeletalMeshCommandBuffers_.size()));
2172 
2173  StartSecondaryCommandBufferRecording(compositeCommandBuffer_,
2174  VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
2175  renderPass, static_cast<int>(RenderSubPasses::COMPOSITE_PASS), VK_NULL_HANDLE);
2176 
2177  vkCmdBindPipeline(compositeCommandBuffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, compositingPipeline_->GetPipeline());
2178 
2179  VkRect2D scissor = { 0,0,swapChainImageExtent };
2180  VkViewport viewport = { 0.f,0.f,static_cast<float>(swapChainImageExtent.width),static_cast<float>(swapChainImageExtent.height),-1.f,1.f };
2181 
2182  vkCmdSetScissor(compositeCommandBuffer_, 0, 1, &scissor);
2183 
2184  VkDescriptorSet descriptors[] = { CompositingAttachmentDescriptorSet_ };
2185 
2186  vkCmdBindDescriptorSets(compositeCommandBuffer_,
2187  VK_PIPELINE_BIND_POINT_GRAPHICS,
2188  compositingPipeline_->GetPipelineLayout(),
2189  0, 1,
2190  descriptors,
2191  0, nullptr);
2192 
2193  VkDeviceSize offsets[] = { 0 };
2194 
2195  vkCmdBindVertexBuffers(compositeCommandBuffer_, 0, 1, &vertexBuffer_, offsets);
2196 
2197  vkCmdDraw(compositeCommandBuffer_, 6, 1, 0, 0);
2198 
2199  EndSecondaryCommandBufferRecording(compositeCommandBuffer_);
2200 
2201  StartSecondaryCommandBufferRecording(gBufferRenderCommandBuffer_,
2202  VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
2203  renderPass, static_cast<int>(RenderSubPasses::RENDER_PASS), VK_NULL_HANDLE);
2204 
2205  vkCmdBindPipeline(gBufferRenderCommandBuffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, gBufferRenderPipeline_->GetPipeline());
2206 
2207  vkCmdSetScissor(gBufferRenderCommandBuffer_, 0, 1, &scissor);
2208 
2209  descriptors[0] = gBufferAttachmentDescriptorSet_;
2210 
2211  vkCmdBindDescriptorSets(gBufferRenderCommandBuffer_,
2212  VK_PIPELINE_BIND_POINT_GRAPHICS,
2213  gBufferRenderPipeline_->GetPipelineLayout(),
2214  0, 1,
2215  descriptors,
2216  0, nullptr);
2217 
2218  VkDescriptorSet sceneDescriptorSet = GetLightDescriptorSet(0, gBufferRenderPipeline_->GetPipelineId(), 1);
2219  if (sceneDescriptorSet == VK_NULL_HANDLE) {
2220  sceneDescriptorSet = CreateLightDescriptorSet(0, gBufferRenderPipeline_->GetPipelineId(), 1, gBufferRenderPipeline_->GetDescriptorSetLayout(1));
2221  }
2222 
2223  uint32_t dynamicOffset[] = { 0 };
2224 
2225  vkCmdBindDescriptorSets(gBufferRenderCommandBuffer_,
2226  VK_PIPELINE_BIND_POINT_GRAPHICS,
2227  gBufferRenderPipeline_->GetPipelineLayout(),
2228  1, 1,
2229  &sceneDescriptorSet,
2230  1, dynamicOffset);
2231 
2232  vkCmdBindVertexBuffers(gBufferRenderCommandBuffer_, 0, 1, &vertexBuffer_, offsets);
2233 
2234  vkCmdDraw(gBufferRenderCommandBuffer_, 6, 1, 0, 0);
2235 
2236  EndSecondaryCommandBufferRecording(gBufferRenderCommandBuffer_);
2237 
2238  }
2239 
2240  void VulkanRenderer::CreateDescriptorPool()
2241  {
2242  if (vulkanDescriptorPools_.size() == 0)
2243  vulkanDescriptorPools_.resize(1);
2244  vulkanDescriptorPools_[0] = eastl::shared_ptr<VulkanDescriptorPool>(new VulkanDescriptorPool(vulkanLogicalDevice_.get()));
2245 
2246  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_SAMPLER, 1000);
2247  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000);
2248  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000);
2249  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000);
2250  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000);
2251  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000);
2252  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2000);
2253  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000);
2254  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000);
2255  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000);
2256  vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000);
2257 
2258  vulkanDescriptorPools_[0]->Compile(11 * 1000);
2259  }
2260 
2261  void VulkanRenderer::InitImGui()
2262  {
2263  vkQueueWaitIdle(vulkanLogicalDevice_->GetGraphicsQueue());
2264 
2265  ImGui_ImplGlfwVulkan_Init_Data initData = {};
2266  initData.allocator = nullptr;
2267  initData.gpu = vulkanPhysicalDevice_->GetPhysicalDevice();
2268  initData.device = vulkanLogicalDevice_->GetDevice();
2269  initData.graphics_queue = vulkanLogicalDevice_->GetGraphicsQueue();
2270  initData.descriptor_pool = vulkanDescriptorPools_[0]->GetPool();
2271  initData.pipeline_cache = VK_NULL_HANDLE;
2272  initData.check_vk_result = check_vk_result;
2273  initData.render_pass = renderPass;
2274  initData.sub_pass = static_cast<int>(RenderSubPasses::IMGUI_PASS);
2275  ImGui_ImplGlfwVulkan_Init(window.lock()->GetGLFWWindow().lock().get(), &initData);
2276 
2277  VkCommandBuffer commandBuffer;
2278 
2279  VkCommandBufferAllocateInfo allocInfo = {};
2280  allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2281  allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2282  allocInfo.commandPool = graphicsCommandPool;
2283  allocInfo.commandBufferCount = 1;
2284 
2285  vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &allocInfo, &commandBuffer);
2286 
2287  VkCommandBufferBeginInfo beginInfo = {};
2288  beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2289  beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
2290 
2291  vkBeginCommandBuffer(commandBuffer, &beginInfo);
2292 
2293  ImGui_ImplGlfwVulkan_CreateFontsTexture(commandBuffer);
2294 
2295  vkEndCommandBuffer(commandBuffer);
2296 
2297  VkSubmitInfo submitInfo = {};
2298  submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2299  submitInfo.commandBufferCount = 1;
2300  submitInfo.pCommandBuffers = &commandBuffer;
2301 
2302  vkQueueSubmit(vulkanLogicalDevice_->GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
2303 
2304  vkDeviceWaitIdle(vulkanLogicalDevice_->GetDevice());
2305 
2306  ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects();
2307 
2308  }
2309 
2310  void VulkanRenderer::CreateSemaphores()
2311  {
2312  imageAvailableSemaphores_.resize(framebuffers.size());
2313  renderFinishedSemaphores_.resize(framebuffers.size());
2314  computeFinishedSemaphores_.resize(framebuffers.size());
2315 
2316  drawingFinishedFences_.resize(framebuffers.size());
2317  computeFinishedFences_.resize(framebuffers.size());
2318 
2319  VkSemaphoreCreateInfo semaphoreInfo = {};
2320  semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2321  for (size_t i = 0, size = framebuffers.size(); i < size; ++i) {
2322  VkResult res = vkCreateSemaphore(vulkanLogicalDevice_->GetDevice(), &semaphoreInfo, nullptr, &imageAvailableSemaphores_[i]);
2323  if (res != VK_SUCCESS) {
2324  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Semaphore 'image available' creation failed";
2325  debug_error("VulkanRenderer", "CreateSemaphores", s);
2326  }
2327  res = vkCreateSemaphore(vulkanLogicalDevice_->GetDevice(), &semaphoreInfo, nullptr, &renderFinishedSemaphores_[i]);
2328  if (res != VK_SUCCESS) {
2329  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Semaphore 'render finished' creation failed";
2330  debug_error("VulkanRenderer", "CreateSemaphores", s);
2331  }
2332  res = vkCreateSemaphore(vulkanLogicalDevice_->GetDevice(), &semaphoreInfo, nullptr, &computeFinishedSemaphores_[i]);
2333  if (res != VK_SUCCESS) {
2334  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Semaphore 'compute finished' creation failed";
2335  debug_error("VulkanRenderer", "CreateSemaphores", s);
2336  }
2337 
2338  VkFenceCreateInfo fenceInfo = {};
2339  fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2340  fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
2341 
2342  res = vkCreateFence(vulkanLogicalDevice_->GetDevice(), &fenceInfo, nullptr, &drawingFinishedFences_[i]);
2343  if (res != VK_SUCCESS) {
2344  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Fence 'drawing finished' creation failed";
2345  debug_error("VulkanRenderer", "CreateSemaphores", s);
2346  }
2347 
2348  res = vkCreateFence(vulkanLogicalDevice_->GetDevice(), &fenceInfo, nullptr, &computeFinishedFences_[i]);
2349  if (res != VK_SUCCESS) {
2350  eastl::string s = eastl::string("[ERROR] [CODE:") + std::to_string(res).c_str() + "] Fence 'compute finished' creation failed";
2351  debug_error("VulkanRenderer", "CreateSemaphores", s);
2352  }
2353 
2354 
2355  }
2356  }
2357 
2358  void VulkanRenderer::CreateCompositingPipeline()
2359  {
2360  compositingPipeline_ = eastl::unique_ptr<VulkanPipeline>(new VulkanPipeline(vulkanLogicalDevice_.get(), this));
2361 
2362  compositingPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::VERTEX_SHADER, "Composite.vert.spv");
2363  compositingPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::FRAGMENT_SHADER, "Composite.frag.spv");
2364 
2365  compositingPipeline_->CreateDescriptorSet();
2366  compositingPipeline_->AddDescriptorSetBinding(0, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
2367  compositingPipeline_->AddDescriptorSetBinding(0, 1, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
2368 
2369  compositingPipeline_->AddVertexInputBindingDescription(0, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
2370  compositingPipeline_->AddVertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32_SFLOAT, 0);
2371 
2372  compositingPipeline_->SetRasterizerSettings(0, 0, VK_POLYGON_MODE_FILL, 1.f, VK_CULL_MODE_NONE);
2373 
2374  compositingPipeline_->SetRenderPassInfo(renderPass, static_cast<int>(RenderSubPasses::COMPOSITE_PASS));
2375 
2376  compositingPipeline_->CreateColorBlendAttachment();
2377 
2378  compositingPipeline_->Compile();
2379 
2380  VkDescriptorSetLayout layouts[] = { compositingPipeline_->GetDescriptorSetLayout(0) };
2381  vulkanDescriptorPools_[0]->AllocateDescriptorSet(1, layouts, &CompositingAttachmentDescriptorSet_);
2382 
2383  vulkanDescriptorPools_[0]->DescriptorSetBindToImage(CompositingAttachmentDescriptorSet_, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, renderImageView, VK_NULL_HANDLE, 0, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1);
2384  vulkanDescriptorPools_[0]->DescriptorSetBindToImage(CompositingAttachmentDescriptorSet_, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, imguiImageView, VK_NULL_HANDLE, 1, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1);
2385 
2386  VkBufferCreateInfo vertexBufferInfo = {};
2387  vertexBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2388  vertexBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2389  vertexBufferInfo.size = sizeof(glm::vec4) * 6;
2390  vertexBufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2391 
2392  VmaAllocationCreateInfo vertexBufferAllocInfo = {};
2393  vertexBufferAllocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
2394 
2395  vmaCreateBuffer(vmaAllocator_, &vertexBufferInfo, &vertexBufferAllocInfo, &vertexBuffer_, &vertexBufferAllocation_, nullptr);
2396 
2397  VkBufferCreateInfo stagingBufferInfo = {};
2398  stagingBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2399  stagingBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2400  stagingBufferInfo.size = sizeof(glm::vec4) * 6;
2401  stagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
2402 
2403  VmaAllocationCreateInfo stagingBufferAllocInfo = {};
2404  stagingBufferAllocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
2405 
2406  VkBuffer stagingBuffer;
2407  VmaAllocation stagingBufferAllocation;
2408  VmaAllocationInfo stagingBufferAllocationInfo;
2409 
2410  vmaCreateBuffer(vmaAllocator_, &stagingBufferInfo, &stagingBufferAllocInfo, &stagingBuffer, &stagingBufferAllocation, &stagingBufferAllocationInfo);
2411 
2412  void* location;
2413 
2414  vkMapMemory(vulkanLogicalDevice_->GetDevice(), stagingBufferAllocationInfo.deviceMemory, stagingBufferAllocationInfo.offset, stagingBufferAllocationInfo.size, 0, &location);
2415 
2416  eastl::vector<glm::vec4> coords = {
2417  { -1.f,1.f, 0.f, 0.f },
2418  { 1.f,1.f, 1.f, 0.f },
2419  { -1.f,-1.f, 0.f, 1.f },
2420  { -1.f,-1.f, 0.f, 1.f },
2421  { 1.f,1.f, 1.f, 0.f },
2422  { 1.f,-1.f, 1.f, 1.f }
2423  };
2424 
2425  memcpy(location, coords.data(), sizeof(glm::vec4) * 6);
2426 
2427  vkUnmapMemory(vulkanLogicalDevice_->GetDevice(), stagingBufferAllocationInfo.deviceMemory);
2428 
2429  VkCommandBufferAllocateInfo cmdAllocInfo = {};
2430  cmdAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2431  cmdAllocInfo.commandPool = graphicsCommandPool;
2432  cmdAllocInfo.commandBufferCount = 1;
2433  cmdAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2434 
2435  VkCommandBuffer cmdBuffer;
2436 
2437  vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &cmdAllocInfo, &cmdBuffer);
2438 
2439  VkCommandBufferBeginInfo cmdBeginInfo = {};
2440  cmdBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2441  cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
2442 
2443  vkBeginCommandBuffer(cmdBuffer, &cmdBeginInfo);
2444 
2445  VkBufferCopy copyRegion = {};
2446  copyRegion.srcOffset = 0; // Optional
2447  copyRegion.dstOffset = 0; // Optional
2448  copyRegion.size = sizeof(glm::vec4) * 6;
2449  vkCmdCopyBuffer(cmdBuffer, stagingBuffer, vertexBuffer_, 1, &copyRegion);
2450 
2451  vkEndCommandBuffer(cmdBuffer);
2452 
2453  VkSubmitInfo submitInfo = {};
2454  submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2455  submitInfo.commandBufferCount = 1;
2456  submitInfo.pCommandBuffers = &cmdBuffer;
2457 
2458  vkQueueSubmit(vulkanLogicalDevice_->GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
2459  vkQueueWaitIdle(vulkanLogicalDevice_->GetGraphicsQueue());
2460 
2461  vmaDestroyBuffer(vmaAllocator_, stagingBuffer, stagingBufferAllocation);
2462 
2463  }
2464 
2465  void VulkanRenderer::CreateGBufferRenderPipeline()
2466  {
2467  gBufferRenderPipeline_ = eastl::unique_ptr<VulkanPipeline>(new VulkanPipeline(vulkanLogicalDevice_.get(), this));
2468 
2469  gBufferRenderPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::VERTEX_SHADER, "G-BufferRender.vert.spv");
2470  gBufferRenderPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::FRAGMENT_SHADER, "G-BufferRender.frag.spv");
2471 
2472  gBufferRenderPipeline_->CreateDescriptorSet();
2473  gBufferRenderPipeline_->AddDescriptorSetLayout(CreateLightDescriptorSetLayout());
2474 
2475  gBufferRenderPipeline_->AddDescriptorSetBinding(0, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
2476  gBufferRenderPipeline_->AddDescriptorSetBinding(0, 1, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
2477  gBufferRenderPipeline_->AddDescriptorSetBinding(0, 2, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
2478 
2479  gBufferRenderPipeline_->AddVertexInputBindingDescription(0, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
2480  gBufferRenderPipeline_->AddVertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32_SFLOAT, 0);
2481 
2482  gBufferRenderPipeline_->SetRasterizerSettings(0, 0, VK_POLYGON_MODE_FILL, 1.f, VK_CULL_MODE_NONE);
2483 
2484  gBufferRenderPipeline_->SetRenderPassInfo(renderPass, static_cast<int>(RenderSubPasses::RENDER_PASS));
2485 
2486  gBufferRenderPipeline_->CreateColorBlendAttachment(VK_TRUE, 15U,
2487  VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD);
2488 
2489  VkStencilOpState front = {};
2490  front.failOp = VK_STENCIL_OP_KEEP;
2491  front.passOp = VK_STENCIL_OP_KEEP;
2492  front.depthFailOp = VK_STENCIL_OP_KEEP;
2493  front.compareOp = VK_COMPARE_OP_EQUAL;
2494  front.reference = 0;
2495  front.compareMask = 0xff;
2496  front.writeMask = 0xff;
2497 
2498  VkStencilOpState back = {};
2499  back.failOp = VK_STENCIL_OP_KEEP;
2500  back.passOp = VK_STENCIL_OP_KEEP;
2501  back.depthFailOp = VK_STENCIL_OP_KEEP;
2502  back.compareOp = VK_COMPARE_OP_EQUAL;
2503  back.reference = 0;
2504  back.compareMask = 0xff;
2505  back.writeMask = 0xff;
2506 
2507  gBufferRenderPipeline_->SetDepthStencilState(VK_TRUE, VK_FALSE, VK_COMPARE_OP_LESS, 0U, 0U, 1.f, VK_TRUE, front, back);
2508 
2509  gBufferRenderPipeline_->Compile();
2510 
2511  VkDescriptorSetLayout layouts[] = { gBufferRenderPipeline_->GetDescriptorSetLayout(0) };
2512  vulkanDescriptorPools_[0]->AllocateDescriptorSet(1, layouts, &gBufferAttachmentDescriptorSet_);
2513 
2514  vulkanDescriptorPools_[0]->DescriptorSetBindToImage(gBufferAttachmentDescriptorSet_, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, albedoImageView, VK_NULL_HANDLE,
2515  0, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1);
2516  vulkanDescriptorPools_[0]->DescriptorSetBindToImage(gBufferAttachmentDescriptorSet_, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, positionImageView, VK_NULL_HANDLE,
2517  1, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1);
2518  vulkanDescriptorPools_[0]->DescriptorSetBindToImage(gBufferAttachmentDescriptorSet_, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, normalImageView, VK_NULL_HANDLE,
2519  2, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1);
2520 
2521  sceneDataBuffer = eastl::unique_ptr<VulkanBuffer>(new VulkanBuffer(
2522  vulkanLogicalDevice_.get(), vmaAllocator_, static_cast<uint32_t>(sizeof(SceneInfo)),
2523  VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, false, graphicsCommandPool));
2524 
2525  lightBuffer = eastl::unique_ptr<VulkanBuffer>(new VulkanBuffer(
2526  vulkanLogicalDevice_.get(), vmaAllocator_, static_cast<uint32_t>(sizeof(Light)*lightData.size()),
2527  VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, false, graphicsCommandPool));
2528 
2529  ambientLightPipeline_ = eastl::unique_ptr<VulkanPipeline>(new VulkanPipeline(vulkanLogicalDevice_.get(), this));
2530 
2531  ambientLightPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::VERTEX_SHADER, "G-BufferRender.vert.spv");
2532  ambientLightPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::FRAGMENT_SHADER, "G-BufferRender.frag.spv");
2533 
2534  ambientLightPipeline_->CreateDescriptorSet();
2535  ambientLightPipeline_->AddDescriptorSetLayout(CreateLightDescriptorSetLayout());
2536 
2537  ambientLightPipeline_->AddDescriptorSetBinding(0, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
2538  ambientLightPipeline_->AddDescriptorSetBinding(0, 1, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
2539  ambientLightPipeline_->AddDescriptorSetBinding(0, 2, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr);
2540 
2541  ambientLightPipeline_->AddVertexInputBindingDescription(0, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
2542  ambientLightPipeline_->AddVertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32_SFLOAT, 0);
2543 
2544  ambientLightPipeline_->SetRasterizerSettings(0, 0, VK_POLYGON_MODE_FILL, 1.f, VK_CULL_MODE_NONE);
2545 
2546  ambientLightPipeline_->SetRenderPassInfo(renderPass, static_cast<int>(RenderSubPasses::RENDER_PASS));
2547 
2548  ambientLightPipeline_->CreateColorBlendAttachment(VK_TRUE, 15U,
2549  VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD);
2550 
2551  ambientLightPipeline_->SetDepthStencilState(VK_TRUE, VK_FALSE, VK_COMPARE_OP_LESS, 0U, 0U, 1.f, VK_FALSE, front, back);
2552 
2553  ambientLightPipeline_->Compile();
2554  }
2555 
2556  void VulkanRenderer::CreateRenderers()
2557  {
2558  vulkanSpriteRenderer = eastl::unique_ptr<VulkanSpriteRenderer>(new VulkanSpriteRenderer(this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get()));
2559  vulkanDebugRenderer = eastl::unique_ptr<VulkanDebugRenderer>(new VulkanDebugRenderer(this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get()));
2560  vulkanStaticMeshRenderer = eastl::unique_ptr<VulkanStaticMeshRenderer>(new VulkanStaticMeshRenderer(this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get()));
2561  vulkanSkeletalMeshRenderer = eastl::unique_ptr<VulkanSkeletalMeshRenderer>(new VulkanSkeletalMeshRenderer(this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get()));
2562  }
2563 
2564  void VulkanRenderer::AllocateThreads()
2565  {
2566  int threadCount = std::thread::hardware_concurrency() - 1;
2567  threads.resize(threadCount);
2568  vulkanDescriptorPools_.resize(threadCount + 1);
2569 
2570  for (size_t i = 0, size = threads.size(); i < size; ++i) {
2571  threads[i] = new ThreadInfo;
2572 
2573  VkCommandPoolCreateInfo info = {};
2574  info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
2575  info.queueFamilyIndex = vulkanPhysicalDevice_->GetQueueFamilies().graphics;
2576 
2577  vkCreateCommandPool(vulkanLogicalDevice_->GetDevice(), &info, nullptr, &(threads[i]->commandPool));
2578 
2579  vulkanDescriptorPools_[i + 1] = eastl::shared_ptr<VulkanDescriptorPool>(new VulkanDescriptorPool(vulkanLogicalDevice_.get()));
2580 
2581  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_SAMPLER, 1000);
2582  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000);
2583  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000);
2584  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000);
2585  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000);
2586  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000);
2587  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2000);
2588  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000);
2589  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000);
2590  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000);
2591  vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000);
2592 
2593  vulkanDescriptorPools_[i + 1]->Compile(11 * 1000);
2594 
2595  threads[i]->threadId = i + 1;
2596  }
2597  }
2598 
2599  void VulkanRenderer::DestroyInstance()
2600  {
2601  vkDestroySurfaceKHR(vulkanInstance_->GetInstance(), surface, nullptr);
2602  vulkanInstance_.reset();
2603  }
2604 
2605  void VulkanRenderer::DestroyLogicalDevice()
2606  {
2607  vulkanLogicalDevice_.reset();
2608  }
2609 
2610  void VulkanRenderer::DestroySwapChain()
2611  {
2612  vkDestroySwapchainKHR(vulkanLogicalDevice_->GetDevice(), swapChain, nullptr);
2613  }
2614 
2615  void VulkanRenderer::DestroySwapChainImageViews()
2616  {
2617  for (int i = 0; i < static_cast<int>(swapChainImageViews.size()); ++i) {
2618  vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), swapChainImageViews[i], nullptr);
2619  }
2620  }
2621 
2622  void VulkanRenderer::DestroyGraphicsCommandPool()
2623  {
2624  vkDestroyCommandPool(vulkanLogicalDevice_->GetDevice(), graphicsCommandPool, nullptr);
2625  }
2626 
2627  void VulkanRenderer::DestroyComputeCommandPool()
2628  {
2629  vkDestroyCommandPool(vulkanLogicalDevice_->GetDevice(), computeCommandPool, nullptr);
2630  }
2631 
2632  void VulkanRenderer::DestroyVmaAllocator()
2633  {
2634  vmaDestroyAllocator(vmaAllocator_);
2635  }
2636 
2637  void VulkanRenderer::DestroyDepthImage()
2638  {
2639  vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), depthImageView, nullptr);
2640 
2641  vmaDestroyImage(vmaAllocator_, depthImage, depthImageAllocation);
2642  }
2643 
2644  void VulkanRenderer::DestroyAttachmentImages()
2645  {
2646  vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), imguiImageView, nullptr);
2647 
2648  vmaDestroyImage(vmaAllocator_, imguiImage, imguiImageAllocation);
2649 
2650  vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), renderImageView, nullptr);
2651 
2652  vmaDestroyImage(vmaAllocator_, renderImage, renderImageAllocation);
2653 
2654  vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), albedoImageView, nullptr);
2655 
2656  vmaDestroyImage(vmaAllocator_, albedoImage, albedoImageAllocation);
2657 
2658  vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), positionImageView, nullptr);
2659 
2660  vmaDestroyImage(vmaAllocator_, positionImage, positionImageAllocation);
2661 
2662  vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), normalImageView, nullptr);
2663 
2664  vmaDestroyImage(vmaAllocator_, normalImage, normalImageAllocation);
2665 
2666  vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), ssaoImageView, nullptr);
2667 
2668  vmaDestroyImage(vmaAllocator_, ssaoImage, ssaoImageAllocation);
2669 
2670  vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), ssaoBlurImageView, nullptr);
2671 
2672  vmaDestroyImage(vmaAllocator_, ssaoBlurImage, ssaoBlurImageAllocation);
2673 
2674  }
2675 
2676  void VulkanRenderer::DestroyRenderPass()
2677  {
2678  vkDestroyRenderPass(vulkanLogicalDevice_->GetDevice(), gBufferPass, nullptr);
2679  vkDestroyRenderPass(vulkanLogicalDevice_->GetDevice(), ssaoPass, nullptr);
2680  vkDestroyRenderPass(vulkanLogicalDevice_->GetDevice(), renderPass, nullptr);
2681  }
2682 
2683  void VulkanRenderer::DestroyFramebuffers()
2684  {
2685  for (int i = 0; i < framebuffers.size(); ++i) {
2686  vkDestroyFramebuffer(vulkanLogicalDevice_->GetDevice(), framebuffers[i], nullptr);
2687  }
2688  vkDestroyFramebuffer(vulkanLogicalDevice_->GetDevice(), gBufferFrameBuffer, nullptr);
2689  vkDestroyFramebuffer(vulkanLogicalDevice_->GetDevice(), ssaoFrameBuffer, nullptr);
2690 
2691  }
2692 
2693  void VulkanRenderer::DestroyDecriptorPool()
2694  {
2695  for (size_t i = 0, size = vulkanDescriptorPools_.size(); i < size; ++i) {
2696  vulkanDescriptorPools_[i].reset();
2697  }
2698  }
2699 
2700  void VulkanRenderer::DestroyImGui() const
2701  {
2702  ImGui_ImplGlfwVulkan_Shutdown();
2703  }
2704 
2705  void VulkanRenderer::DestroySemaphores()
2706  {
2707  for (size_t i = 0, size = imageAvailableSemaphores_.size(); i < size; ++i) {
2708  vkDestroySemaphore(vulkanLogicalDevice_->GetDevice(), imageAvailableSemaphores_[i], nullptr);
2709  vkDestroySemaphore(vulkanLogicalDevice_->GetDevice(), renderFinishedSemaphores_[i], nullptr);
2710  vkDestroySemaphore(vulkanLogicalDevice_->GetDevice(), computeFinishedSemaphores_[i], nullptr);
2711 
2712  vkDestroyFence(vulkanLogicalDevice_->GetDevice(), drawingFinishedFences_[i], nullptr);
2713  vkDestroyFence(vulkanLogicalDevice_->GetDevice(), computeFinishedFences_[i], nullptr);
2714  }
2715 
2716  }
2717 
2718  void VulkanRenderer::DestroyCompositingPipeline()
2719  {
2720  compositingPipeline_.reset();
2721  vmaDestroyBuffer(vmaAllocator_, vertexBuffer_, vertexBufferAllocation_);
2722  }
2723 
2724  void VulkanRenderer::DestroyGBufferRenderPipeline()
2725  {
2726  gBufferRenderPipeline_.reset();
2727  ambientLightPipeline_.reset();
2728 
2729  sceneDataBuffer.reset();
2730  lightBuffer.reset();
2731  }
2732 
2733  void VulkanRenderer::DestroyRenderers()
2734  {
2735  vulkanSpriteRenderer.reset();
2736  vulkanDebugRenderer.reset();
2737  vulkanStaticMeshRenderer.reset();
2738  vulkanSkeletalMeshRenderer.reset();
2739  }
2740 
2741  void VulkanRenderer::DestroyThreads()
2742  {
2743  for (size_t i = 0, size = threads.size(); i < size; ++i) {
2744  if (threads[i]->thread.joinable())
2745  threads[i]->thread.join();
2746  vkDestroyCommandPool(vulkanLogicalDevice_->GetDevice(), threads[i]->commandPool, nullptr);
2747  delete threads[i];
2748  }
2749  }
2750 
2751  VkFormat VulkanRenderer::FindSupportedDepthFormat(const eastl::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features)
2752  {
2753  if (!vulkanPhysicalDevice_)
2754  return VK_FORMAT_UNDEFINED;
2755  for (VkFormat format : candidates) {
2756  VkFormatProperties props;
2757  vkGetPhysicalDeviceFormatProperties(vulkanPhysicalDevice_->GetPhysicalDevice(), format, &props);
2758  if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures&features) == features) {
2759  return format;
2760  }
2761  else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures&features) == features) {
2762  return format;
2763  }
2764  }
2765  return VK_FORMAT_UNDEFINED;
2766  }
2767 
2768  void VulkanRenderer::GenerateSecondaryCommandBuffers(VkCommandBuffer * buffers, uint32_t count)
2769  {
2770  VkCommandBufferAllocateInfo allocInfo = {};
2771  allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2772  allocInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
2773  allocInfo.commandPool = graphicsCommandPool;
2774  allocInfo.commandBufferCount = count;
2775 
2776  vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &allocInfo, buffers);
2777  }
2778 
2779  void VulkanRenderer::DestroySecondaryCommandBuffers(VkCommandBuffer * buffers, uint32_t count)
2780  {
2781  vkFreeCommandBuffers(vulkanLogicalDevice_->GetDevice(), graphicsCommandPool, count, buffers);
2782  }
2783 
2784  void VulkanRenderer::RestructureLights()
2785  {
2786  eastl::array<Light, 1024> tempData = lightData;
2787  lightData.fill({});
2788  eastl::map<eastl::string, LightInfo>::iterator it = lights.begin();
2789  eastl::map<eastl::string, LightInfo>::iterator end = lights.end();
2790  for (size_t location = 0; it != end; ++it) {
2791  if (it->second.active) {
2792  lightData[location] = it->second.light;
2793  it->second.lightDataIndex = location;
2794  location++;
2795  activeLights = static_cast<int>(location);
2796  }
2797  }
2798 
2799  lightDataRestructured = false;
2800  lightDataChanged = true;
2801  }
2802 
2803  void VulkanRenderer::UpdateLightData()
2804  {
2805  lightBuffer->UpdateBuffer(lightData.data(), 0, static_cast<uint32_t>(sizeof(Light)*lightData.size()));
2806 
2807  if (activeLights != scene.lightCount) {
2808  scene.lightCount = activeLights;
2809  }
2810 
2811  lightDataChanged = false;
2812  }
2813 
2814  VulkanRenderer::ThreadInfo * VulkanRenderer::GetFreeThread()
2815  {
2816  for (size_t i = 0, size = threads.size(); i < size; ++i) {
2817  if (threads[i]->initialized == false)
2818  return threads[i];
2819 
2820  auto status = threads[i]->future.wait_for(std::chrono::milliseconds(0));
2821 
2822  if (status == std::future_status::ready) {
2823  if (threads[i]->thread.joinable())
2824  threads[i]->thread.join();
2825  threads[i]->initialized = false;
2826  return threads[i];
2827  }
2828  }
2829  return nullptr;
2830  }
2831 
2832  void VulkanRenderer::JoinAllThreads()
2833  {
2834  for (size_t i = 0, size = threads.size(); i < size; ++i) {
2835  if (threads[i]->thread.joinable())
2836  threads[i]->thread.join();
2837  }
2838  }
2839 
2840  void VulkanRenderer::ResetCommandPools()
2841  {
2842  for (size_t i = 0, size = threads.size(); i < size; ++i) {
2843  vkResetCommandPool(vulkanLogicalDevice_->GetDevice(), threads[i]->commandPool, 0);
2844  }
2845  }
2846 
2847  void VulkanRenderer::StartSecondaryCommandBufferRecording(VkCommandBuffer buffer, VkCommandBufferUsageFlags flags, VkRenderPass renderPass, uint32_t subPass, VkFramebuffer framebuffer) const
2848  {
2849  VkCommandBufferInheritanceInfo inheritence = {};
2850  inheritence.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
2851  inheritence.occlusionQueryEnable = VK_FALSE;
2852  inheritence.renderPass = renderPass;
2853  inheritence.subpass = subPass;
2854  inheritence.framebuffer = framebuffer;
2855 
2856  VkCommandBufferBeginInfo info = {};
2857  info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2858  info.flags = flags;
2859  info.pInheritanceInfo = &inheritence;
2860 
2861  vkBeginCommandBuffer(buffer, &info);
2862  }
2863 
2864  void VulkanRenderer::EndSecondaryCommandBufferRecording(VkCommandBuffer buffer) const
2865  {
2866  vkEndCommandBuffer(buffer);
2867  }
2868 
2869 
2870 } //namespace Engine
2871 #endif
LIGHT_AMBIENT_LIGHT
Definition: Light.hpp:10
Definition: Light.hpp:17
#define debug_error(debug_class, function, value)
This functions logs a debug error to the log and console. This does not halt the program! ...
Definition: Logging.hpp:30
LIGHT_SPOT_LIGHT
Definition: Light.hpp:10
LIGHT_POINT_LIGHT
Definition: Light.hpp:10
LIGHT_DIRECTIONAL_LIGHT
Definition: Light.hpp:10
enum ENGINE_API LightType
Enum containing the different types of lights that can be created.
Definition: Light.hpp:9
IMGUI_API void Render()
Definition: imgui.cpp:2769